{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Basic Calculator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Hard"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #stack #recursion #math #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #栈 #递归 #数学 #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: calculate"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #基本计算器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你一个字符串表达式 <code>s</code> ，请你实现一个基本计算器来计算并返回它的值。</p>\n",
    "\n",
    "<p>注意:不允许使用任何将字符串作为数学表达式计算的内置函数，比如 <code>eval()</code> 。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"1 + 1\"\n",
    "<strong>输出：</strong>2\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \" 2-1 + 2 \"\n",
    "<strong>输出：</strong>3\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"(1+(4+5+2)-3)+(6+8)\"\n",
    "<strong>输出：</strong>23\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= s.length &lt;= 3&nbsp;* 10<sup>5</sup></code></li>\n",
    "\t<li><code>s</code> 由数字、<code>'+'</code>、<code>'-'</code>、<code>'('</code>、<code>')'</code>、和 <code>' '</code> 组成</li>\n",
    "\t<li><code>s</code> 表示一个有效的表达式</li>\n",
    "\t<li><font color=\"#c7254e\"><font face=\"Menlo, Monaco, Consolas, Courier New, monospace\"><span style=\"font-size:12.6px\"><span style=\"background-color:#f9f2f4\">'+'</span></span></font></font> 不能用作一元运算(例如， <font color=\"#c7254e\"><font face=\"Menlo, Monaco, Consolas, Courier New, monospace\"><span style=\"font-size:12.6px\"><span style=\"background-color:#f9f2f4\">\"+1\"</span></span></font></font>&nbsp;和 <code>\"+(2 + 3)\"</code>&nbsp;无效)</li>\n",
    "\t<li><font color=\"#c7254e\"><font face=\"Menlo, Monaco, Consolas, Courier New, monospace\"><span style=\"font-size:12.6px\"><span style=\"background-color:#f9f2f4\">'-'</span></span></font></font> 可以用作一元运算(即 <font color=\"#c7254e\"><font face=\"Menlo, Monaco, Consolas, Courier New, monospace\"><span style=\"font-size:12.6px\"><span style=\"background-color:#f9f2f4\">\"-1\"</span></span></font></font>&nbsp;和 <code>\"-(2 + 3)\"</code>&nbsp;是有效的)</li>\n",
    "\t<li>输入中不存在两个连续的操作符</li>\n",
    "\t<li>每个数字和运行的计算将适合于一个有符号的 32位 整数</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [basic-calculator](https://leetcode.cn/problems/basic-calculator/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [basic-calculator](https://leetcode.cn/problems/basic-calculator/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"1 + 1\"', '\" 2-1 + 2 \"', '\"(1+(4+5+2)-3)+(6+8)\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        l1, o1 = 0, 1 # 1 for +, -1 for -1\n",
    "        l2, o2 = 1, 1 # 1 for *, -1 for /\n",
    "        idx = 0\n",
    "        # s = ''.join(list(filter(lambda c : c != ' ', s))) #remove all spaces\n",
    "        last = '('\n",
    "        while idx < len(s):                        \n",
    "            if s[idx].isdigit():\n",
    "                num = int(s[idx])\n",
    "                while idx+1 < len(s) and s[idx+1].isdigit():\n",
    "                    idx += 1\n",
    "                    num = num * 10 + int(s[idx])\n",
    "                l2 = l2 * num if o2==1 else int(l2/num)\n",
    "            elif s[idx] == '(':\n",
    "                stack += [l1, o1, l2, o2]\n",
    "                l1, o1 = 0, 1\n",
    "                l2, o2 = 1, 1                \n",
    "            elif s[idx] == ')':\n",
    "                num = l1 + o1*l2\n",
    "                o2, l2 = stack.pop(), stack.pop()\n",
    "                o1, l1 = stack.pop(), stack.pop()\n",
    "                l2 = l2 * num if o2 == 1 else int(l2/num)\n",
    "            elif s[idx] in '+-':                \n",
    "                if idx > 0 and last != '(': # - can be negative sign\n",
    "                    l1 = l1 + o1*l2\n",
    "                o1 = 1 if s[idx] == '+' else -1\n",
    "                l2, o2 = 1, 1\n",
    "            elif s[idx] in '*/':\n",
    "                o2 = 1 if s[idx] == '*' else -1\n",
    "            if s[idx] != ' ':\n",
    "                last = s[idx]\n",
    "            idx += 1\n",
    "        return l1 + o1*l2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        stack1, stack2 = [], []\n",
    "        num = 0\n",
    "        for item in s:\n",
    "            if item.isdigit():\n",
    "                num = num * 10 + ord(item) - ord(\"0\")\n",
    "            elif item == \" \":\n",
    "                continue\n",
    "            else:\n",
    "                stack1.append(num)\n",
    "                num = 0\n",
    "                if not stack2:\n",
    "                    stack2.append(item)\n",
    "                else:\n",
    "                    while stack2 and self.compare(stack2[-1], item):\n",
    "                        num1, num2 = stack1.pop(), stack1.pop()\n",
    "                        stack1.append(self.operate(stack2.pop(), num2, num1))\n",
    "                    stack2.append(item)\n",
    "        stack1.append(num)\n",
    "        while stack2 and stack1:\n",
    "            num1, num2 = stack1.pop(), stack1.pop()\n",
    "            stack1.append(self.operate(stack2.pop(), num2, num1))\n",
    "        return stack1.pop()\n",
    "\n",
    "    def operate(self, operator, num1, num2):\n",
    "        if operator == \"+\": return num1 + num2\n",
    "        if operator == \"-\": return num1 - num2\n",
    "        if operator == \"*\": return num1 * num2\n",
    "        if operator == \"/\": return num1 // num2\n",
    "\n",
    "    def compare(self, op1, op2):\n",
    "        # op2<=op1返回True\n",
    "        # 否则返回False\n",
    "        if (op1 == \"+\" or op1 == \"-\") and (op2 == '+' or op2 == \"-\"):\n",
    "            return True\n",
    "        if (op1 == \"*\" or op1 == \"/\") and (op2 == '*' or op2 == '/'):\n",
    "            return True\n",
    "        if (op1 == \"*\" or op1 == \"/\") and (op2 == '+' or op2 == \"-\"):\n",
    "            return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calcu_two_num(self, a, b, opt):\n",
    "        if opt == '+': return a + b\n",
    "        elif opt == '-': return a - b\n",
    "        elif opt == '/': return a // b\n",
    "        else: return a * b\n",
    "        \n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s += 'u'\n",
    "        opt_rank = {'+': 0, '-': 0, '*': 1, '/': 1}\n",
    "        opt_stack = []\n",
    "        num_stack = []\n",
    "        numend = True\n",
    "        for char in s:\n",
    "            if char.isdigit():\n",
    "                if numend: num_stack.append(int(char))\n",
    "                else: num_stack[-1]  = num_stack[-1] * 10 + int(char)\n",
    "                numend = False\n",
    "            elif char != ' ':\n",
    "                numend = True\n",
    "                opt_stack.append(char)\n",
    "                if len(opt_stack) > 2:\n",
    "                    if opt_rank[opt_stack[-2]] > opt_rank[opt_stack[-3]]:\n",
    "                        num_stack[-2:] = (self.calcu_two_num(num_stack[-2], num_stack[-1], opt_stack[-2]),)\n",
    "                        del opt_stack[-2]\n",
    "                    else:\n",
    "                        num_stack[-3:-1] = (self.calcu_two_num(num_stack[-3], num_stack[-2], opt_stack[-3]),)\n",
    "                        del opt_stack[-3]\n",
    "            else:\n",
    "                numend = True\n",
    "        if len(num_stack) == 1: return num_stack[0]\n",
    "        else: return self.calcu_two_num(num_stack[-2], num_stack[-1], opt_stack[-2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        num,stack,sign=0,[0],'+'\n",
    "        \n",
    "        for i in range(len(s)):\n",
    "            if s[i].isdigit():\n",
    "                num=num*10+int(s[i])\n",
    "                \n",
    "            if (not s[i].isdigit() and s[i]!=' ') or i==len(s)-1:\n",
    "                if sign=='+':\n",
    "                    stack.append(num)\n",
    "                    \n",
    "                if sign=='-':\n",
    "                    stack.append(-num)\n",
    "                    \n",
    "                if sign=='*':\n",
    "                    stack.append(stack.pop(-1)*num)\n",
    "                    \n",
    "                if sign=='/':\n",
    "                    stack.append(int(stack.pop(-1)/num))\n",
    "                    \n",
    "                sign=s[i]\n",
    "                num=0\n",
    "                \n",
    "        res=0\n",
    "        \n",
    "        for num in stack:\n",
    "            res+=num\n",
    "            \n",
    "        return res\n",
    "                    \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s += \"+\"\n",
    "        sign = \"+\"\n",
    "        curr = 0\n",
    "        res = []\n",
    "        for x in s:\n",
    "            if x.isdigit():\n",
    "                curr = curr * 10 + int(x)\n",
    "            elif x != \" \":\n",
    "                if sign == \"+\":\n",
    "                    res.append(curr)\n",
    "                elif sign == \"-\":\n",
    "                    res.append(-curr)\n",
    "                elif sign == \"*\":\n",
    "                    res.append(res.pop() * curr)\n",
    "                else:\n",
    "                    res.append(int(res.pop() / curr))\n",
    "                curr = 0\n",
    "                sign = x\n",
    "        return sum(res)\n",
    "                \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s.replace(' ','')\n",
    "        def sele(s,k):\n",
    "            if k==1:\n",
    "                b=s.split('+')\n",
    "                out=sele(b[0],2)\n",
    "                for i in b[1:]:\n",
    "                    out+=sele(i,2)\n",
    "                return out\n",
    "            if k==2:\n",
    "                b=s.split('-')\n",
    "                out=sele(b[0],3)\n",
    "                for i in b[1:]:\n",
    "                    out-=sele(i,3)\n",
    "                return out\n",
    "            if k==3:\n",
    "                fu=1\n",
    "                a,b,out=0,0,1\n",
    "                for i in range(len(s)):\n",
    "                    if s[i]=='*':\n",
    "                        out=int(out*int(s[a:b])**fu)\n",
    "                        a,b=i+1,i+1\n",
    "                        fu=1\n",
    "                    elif s[i]=='/':\n",
    "                        out=int(out*int(s[a:b])**fu)\n",
    "                        a,b=i+1,i+1\n",
    "                        fu=-1\n",
    "                    else:\n",
    "                        b+=1\n",
    "                out=int(out*int(s[a:b])**fu)\n",
    "                return out\n",
    "        return sele(s,1)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        stack=[]\n",
    "        num=0\n",
    "        for w in s:\n",
    "            if w==' ':\n",
    "                continue\n",
    "            if w in '+-*/':\n",
    "                if len(stack)>0 and stack[-1] in '*/':\n",
    "                    oper=stack.pop()\n",
    "                    a=stack.pop()\n",
    "                    if oper=='*':\n",
    "                        stack.append(a*num)\n",
    "                    else:\n",
    "                        stack.append(a//num)\n",
    "                else:\n",
    "                    stack.append(num)\n",
    "                stack.append(w)\n",
    "                num=0\n",
    "            else:\n",
    "                num=num*10+int(w)\n",
    "        stack.append(num)\n",
    "        if len(stack)>1 and stack[-2] in '*/':\n",
    "            b,op,a=stack.pop(),stack.pop(),stack.pop()\n",
    "            if op=='*':\n",
    "                stack.append(a*b)\n",
    "            else:\n",
    "                stack.append(a//b)\n",
    "        #print(stack)\n",
    "        while len(stack)>1:\n",
    "            a,op,b=stack.pop(0),stack.pop(0),stack.pop(0)\n",
    "            print(a,op,b)\n",
    "            if op=='+':\n",
    "                stack.insert(0,a+b) \n",
    "            else :\n",
    "                stack.insert(0,a-b)\n",
    "        return stack[0]\n",
    "        \n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: 'str') -> 'int':\n",
    "        s += '+'      #这样就不用单独处理最后一个数字了\n",
    "        n = 0\n",
    "        sign = '+'    #也处理了特殊情况，只有一个数字没有运算符\n",
    "        stk = []\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                n = 10 * n + ord(c) - 48\n",
    "            elif c != ' ':\n",
    "                if sign == '+':\n",
    "                    stk.append(n)\n",
    "                elif sign == '-':\n",
    "                    stk.append(-n)\n",
    "                elif sign == '*':\n",
    "                    stk.append(stk.pop() * n)\n",
    "                elif sign == '/':\n",
    "                    stk.append(int(stk.pop() / n))\n",
    "                sign = c\n",
    "                n = 0\n",
    "        print(stk)\n",
    "        return sum(stk)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        nums = []\n",
    "        op = []\n",
    "        ans = 0\n",
    "        a = ''\n",
    "        for i in s:\n",
    "            if i == ' ':\n",
    "                continue\n",
    "            if i == '*' or i == '/' or i == '+' or i == '-':\n",
    "                nums.append(int(a))\n",
    "                nums.append(i)\n",
    "                a = ''\n",
    "            else:\n",
    "                a += i\n",
    "        nums.append(int(a))\n",
    "        nums = nums[::-1]\n",
    "        return self.cal(nums)    \n",
    "\n",
    "    def cal(self, stack):\n",
    "        ans = 0\n",
    "        pre = []\n",
    "        \n",
    "        while stack:\n",
    "            item = stack.pop()\n",
    "            if item == '+' or item == '-' :\n",
    "                a = self.flush(pre)\n",
    "                pre=[]\n",
    "                pre.append(a) \n",
    "                pre.append(item)\n",
    "            elif item =='*':\n",
    "                a = pre.pop()\n",
    "                b = stack.pop()\n",
    "                pre.append(a * b)\n",
    "            elif item =='/':\n",
    "                a = pre.pop()\n",
    "                b = stack.pop()\n",
    "                pre.append(a // b)\n",
    "            else:\n",
    "                pre.append(item)\n",
    "        return self.flush(pre)\n",
    "    def flush(self,s):\n",
    "        n = len(s)\n",
    "        if n == 0 :\n",
    "            return 0\n",
    "        elif n==1 :\n",
    "            return s[0]\n",
    "        else:\n",
    "            a = s[0]\n",
    "            b = s[-1]\n",
    "            op = s[1]\n",
    "            if op == '+':\n",
    "                return a + b\n",
    "            else:\n",
    "                return a - b\n",
    "                \n",
    "            \n",
    "                \n",
    "        return ans\n",
    "            \n",
    "                \n",
    "                \n",
    "\n",
    "\n",
    "                \n",
    "                \n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: 'str') -> 'int':\n",
    "        \n",
    "        def proc(a:'int',b:'int',c:'str') -> 'int':\n",
    "            if c==\"+\":\n",
    "                return a+b\n",
    "            elif c==\"-\":\n",
    "                return a-b\n",
    "            elif c==\"*\":\n",
    "                return a*b\n",
    "            else:\n",
    "                return int(a/b)\n",
    "        \n",
    "        #...\n",
    "        t,n=[],0\n",
    "        for c in s:\n",
    "            if c !=\" \":\n",
    "                n+=1\n",
    "                t.append(c)\n",
    "        s = \"\".join(t)\n",
    "        #......\n",
    "        nums,opts=[],[]\n",
    "        i = 0\n",
    "        while i<n :\n",
    "            if s[i] in \"+-*/\":\n",
    "                opts.append(s[i])\n",
    "                i+=1\n",
    "            else:\n",
    "                num = 0\n",
    "                while i<n and s[i] not in \"+-*/\":\n",
    "                    num = num*10 + int(s[i])\n",
    "                    i += 1\n",
    "                nums.append(num)\n",
    "        #.......\n",
    "        i,j,n = 0,0,len(opts)\n",
    "        while i<n :\n",
    "            if opts[i] in \"*/\":\n",
    "                nums[j] = proc(nums[j],nums[i+1],opts[i])\n",
    "            else:\n",
    "                nums[j+1] = nums[i+1]\n",
    "                opts[j] = opts[i]\n",
    "                j+=1\n",
    "            i+=1\n",
    "        #........\n",
    "        re=nums[0]\n",
    "        for i in range(j):\n",
    "            re = proc(re,nums[i+1],opts[i])\n",
    "        return re"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s_num = ''\n",
    "        tran_list = []\n",
    "        for i in s:\n",
    "            if i in ['+','-','*','/']:\n",
    "                tran_list.append(int(s_num))\n",
    "                tran_list.append(i)\n",
    "                s_num = ''\n",
    "            elif i != ' ':\n",
    "                s_num += i\n",
    "        tran_list.append(int(s_num))\n",
    "        # print(tran_list)\n",
    "        op_stack = []\n",
    "        while tran_list:\n",
    "            v = tran_list.pop(0)\n",
    "            if v == '*':\n",
    "                v_op = op_stack.pop()*tran_list.pop(0)\n",
    "                op_stack.append(v_op)\n",
    "            elif v == '/':\n",
    "                v_op = op_stack.pop() // tran_list.pop(0)\n",
    "                op_stack.append(v_op)\n",
    "            else:\n",
    "                op_stack.append(v)\n",
    "        result = 0\n",
    "        for i in range(len(op_stack)):\n",
    "            if op_stack[i] == '-':\n",
    "                op_stack[i+1] = - op_stack[i+1]\n",
    "            elif isinstance(op_stack[i],int) :\n",
    "                result += op_stack[i]\n",
    "        return result\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        stack_num = [0]*n\n",
    "        top_num = -1\n",
    "        stack_op = [None]*n\n",
    "        top_op = -1\n",
    "        def compute(num1,num2,op):\n",
    "            if op == '+':\n",
    "                return num1 + num2\n",
    "            elif op == '-':\n",
    "                return num1 - num2\n",
    "            elif op == '/':\n",
    "                return int(num1/num2)\n",
    "            elif op == '*':\n",
    "                return num1*num2\n",
    "            else:\n",
    "                raise ValueError(\"No such operator\")\n",
    "        priority = {'+':0,'-':0,'*':1,'/':1}\n",
    "        while i < n:\n",
    "            c = s[i]\n",
    "            if c == ' ':\n",
    "                i+=1\n",
    "                continue\n",
    "            elif '0'<= c <= '9':\n",
    "                j = i\n",
    "                while j < n and '0'<= s[j] <= '9':\n",
    "                    j += 1\n",
    "                stack_num[top_num+1] = int(s[i:j])\n",
    "                top_num+=1\n",
    "                i = j - 1\n",
    "            else:\n",
    "                while top_op >=0 and priority[stack_op[top_op]] >= priority[c]:\n",
    "                    stack_num[top_num-1] = compute(stack_num[top_num-1],stack_num[top_num],stack_op[top_op])\n",
    "                    top_num -= 1\n",
    "                    top_op-=1\n",
    "                stack_op[top_op+1]=c\n",
    "                top_op += 1\n",
    "            i+=1\n",
    "        while top_op >= 0:\n",
    "            stack_num[top_num - 1] = compute(stack_num[top_num - 1], stack_num[top_num],  stack_op[top_op])\n",
    "            top_num -= 1\n",
    "            top_op -= 1\n",
    "        return stack_num[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def calarr(xx):\n",
    "    num = []\n",
    "    symbol =[]\n",
    "    sum = 0\n",
    "    for a in range(len(xx)):\n",
    "        if xx[0] not in['+','-','/','*']:\n",
    "            num.append(xx[0])\n",
    "            del xx[0]\n",
    "        elif xx[0] == '*':\n",
    "            rel=num.pop()*xx[1]\n",
    "            del xx[0:2]\n",
    "            num.append(rel)\n",
    "        elif xx[0] == '/':\n",
    "            rel=int(num.pop()/xx[1])\n",
    "            del xx[0:2]\n",
    "            num.append(rel)\n",
    "        elif xx[0] == '+':\n",
    "            symbol.append('+')\n",
    "            del xx[0]\n",
    "        elif xx[0] == '-':\n",
    "            symbol.append('-')\n",
    "            del xx[0]\n",
    "        if xx == []:\n",
    "            num=num[::-1]\n",
    "            symbol=symbol[::-1]\n",
    "            while len(num)!=1:\n",
    "                sy = symbol.pop()\n",
    "                if sy == '+':\n",
    "                    rel = num.pop()+num.pop()\n",
    "                    num.append(rel)\n",
    "                if sy == '-':\n",
    "                    rel = num.pop()-num.pop()\n",
    "                    num.append(rel)\n",
    "            result = num[0]         \n",
    "            return result    \n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s=s.replace(' ','')\n",
    "        unit = ''\n",
    "        sl=[]\n",
    "        for x in s:\n",
    "            if (x not in ['+','-','*','/']):\n",
    "                unit +=x\n",
    "            else:\n",
    "                sl.append(int(unit))\n",
    "                unit = ''\n",
    "                sl.append(x)\n",
    "        sl.append(int(unit))\n",
    "        return calarr(sl)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        \n",
    "        l = []\n",
    "        ts = \"\"\n",
    "        for i in s:\n",
    "            if i == \" \":\n",
    "                if ts != \"\":\n",
    "                    l.append(ts)\n",
    "                    ts = \"\"\n",
    "                continue\n",
    "            elif i == \"+\" or i == \"-\" or i == \"*\" or i == \"/\":\n",
    "                if ts != \"\":\n",
    "                    l.append(ts)\n",
    "                    ts = \"\"\n",
    "                l.append(i)\n",
    "            else:\n",
    "                ts += i\n",
    "        \n",
    "        if ts != \"\":\n",
    "            l.append(ts)\n",
    "        \n",
    "        lt = []\n",
    "        i = 0\n",
    "        while i < len(l):\n",
    "            if l[i] == \"*\":\n",
    "                t = lt.pop()\n",
    "                i += 1\n",
    "                lt.append(int(t) * int(l[i]))\n",
    "            elif l[i] == \"/\":\n",
    "                t = lt.pop()\n",
    "                i += 1\n",
    "                lt.append(int(int(t) / int(l[i])))\n",
    "            else:\n",
    "                lt.append(l[i])\n",
    "            i += 1\n",
    "        \n",
    "        r = int(lt[0])\n",
    "        i = 1\n",
    "        while i < len(lt):\n",
    "            if lt[i] == \"+\":\n",
    "                i += 1\n",
    "                r += int(lt[i])\n",
    "            elif lt[i] == \"-\":\n",
    "                i += 1\n",
    "                r -= int(lt[i])\n",
    "            i += 1\n",
    "        return r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        oprands = []\n",
    "        oprs = ['#']\n",
    "        OPRS = '+-*/'\n",
    "        cur = ''\n",
    "        res = 0\n",
    "        for e in s:\n",
    "            if e:\n",
    "                if e.isdigit():\n",
    "                    cur += e\n",
    "                elif e != ' ':\n",
    "                    if cur:\n",
    "                        oprands.append(cur)\n",
    "                        cur = ''\n",
    "                    op_pri =  OPRS.index(e) // 2\n",
    "                    while oprs[-1] != '#' and  (OPRS.index(oprs[-1]) // 2 >= op_pri):\n",
    "                        num2 = oprands.pop()\n",
    "                        num1 = oprands.pop()\n",
    "                        op = oprs.pop()\n",
    "                        res = int(eval(num1 + op + num2))\n",
    "                        oprands.append(str(res))\n",
    "                    oprs.append(e)\n",
    "        if cur:\n",
    "            oprands.append(cur)\n",
    "            cur = ''\n",
    "        while oprs[-1] != '#':\n",
    "            num2 = oprands.pop()\n",
    "            num1 = oprands.pop()\n",
    "            op = oprs.pop()\n",
    "            res = int(eval(num1 + op + num2))\n",
    "            oprands.append(str(res))\n",
    "        if oprands:\n",
    "            return int(oprands[0])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        oprands = []\n",
    "        oprs = ['#']\n",
    "        OPRS = '+-*/'\n",
    "        cur = ''\n",
    "        res = 0\n",
    "        for e in s:\n",
    "            if e:\n",
    "                if e.isdigit():\n",
    "                    cur += e\n",
    "                elif e != ' ':\n",
    "                    if cur:\n",
    "                        oprands.append(cur)\n",
    "                        cur = ''\n",
    "                    op_pri =  OPRS.index(e) // 2\n",
    "                    while oprs[-1] != '#' and  (OPRS.index(oprs[-1]) // 2 >= op_pri):\n",
    "                        num2 = oprands.pop()\n",
    "                        num1 = oprands.pop()\n",
    "                        op = oprs.pop()\n",
    "                        res = int(eval(num1 + op + num2))\n",
    "                        oprands.append(str(res))\n",
    "                    oprs.append(e)\n",
    "        if cur:\n",
    "            oprands.append(cur)\n",
    "            cur = ''\n",
    "        while oprs[-1] != '#':\n",
    "            num2 = oprands.pop()\n",
    "            num1 = oprands.pop()\n",
    "            op = oprs.pop()\n",
    "            res = int(eval(num1 + op + num2))\n",
    "            oprands.append(str(res))\n",
    "        if oprands:\n",
    "            return int(oprands[0])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        result = 0\n",
    "        num = 0\n",
    "        neg = False\n",
    "        i = 0\n",
    "        while i < len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '+' or s[i] == '-':\n",
    "                if neg:\n",
    "                    result -= num\n",
    "                else:\n",
    "                    result += num\n",
    "                num = 0\n",
    "                neg = (s[i] == '-')\n",
    "                i += 1\n",
    "            elif s[i] == '*' or s[i] == '/':\n",
    "                c = s[i]\n",
    "                i += 1\n",
    "                num2 = 0\n",
    "                while i < len(s) and (s[i] == ' ' or s[i].isdigit()):\n",
    "                    if s[i].isdigit():\n",
    "                        num2 = num2 * 10 + int(s[i])\n",
    "                    i += 1\n",
    "                if c == '*':\n",
    "                    num *= num2\n",
    "                else:\n",
    "                    num //= num2\n",
    "            else:\n",
    "                num = num * 10 + int(s[i])\n",
    "                i += 1\n",
    "        return result - num if neg else result + num "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def cal(a,b,ope):\n",
    "            if ope=='+':\n",
    "                return a+b\n",
    "            elif ope=='-':\n",
    "                return a-b\n",
    "            elif ope=='*':\n",
    "                return a*b\n",
    "            else:\n",
    "                return int(a/b)\n",
    "        s=s.replace(\" \",\"\")\n",
    "        op={'+':0,'-':0,'*':1,'/':1}\n",
    "        nums=[]\n",
    "        ops=[]\n",
    "        index=0\n",
    "        while index<len(s):\n",
    "            if s[index].isdigit():\n",
    "                res=\"\"\n",
    "                while index<len(s) and s[index].isdigit():\n",
    "                    res=res+s[index]\n",
    "                    index+=1\n",
    "                nums.append(int(res))\n",
    "            else:\n",
    "                if not ops or op[s[index]]>op[ops[-1]]:\n",
    "                        ops.append(s[index])\n",
    "                else:\n",
    "                    while ops and op[s[index]]<=op[ops[-1]]:\n",
    "                        last_op=ops.pop()\n",
    "                        n2=nums.pop()\n",
    "                        n1=nums.pop()\n",
    "                        nums.append(cal(n1,n2,last_op))\n",
    "                    ops.append(s[index])\n",
    "                index+=1\n",
    "            \n",
    "            \n",
    "        # for item in s:\n",
    "        #     if item.isdigit():\n",
    "        #         nums.append(int(item))\n",
    "        #     else:\n",
    "        #         if not ops or op[item]>op[ops[-1]]:\n",
    "        #             ops.append(item)\n",
    "        #         else:\n",
    "        #             while ops and op[item]<=op[ops[-1]]:\n",
    "        #                 last_op=ops.pop()\n",
    "        #                 n2=nums.pop()\n",
    "        #                 n1=nums.pop()\n",
    "        #                 nums.append(cal(n1,n2,last_op))\n",
    "        #             ops.append(item)\n",
    "        while ops:\n",
    "            last_op=ops.pop()\n",
    "            n2=nums.pop()\n",
    "            n1=nums.pop()\n",
    "            nums.append(cal(n1,n2,last_op))\n",
    "        return nums[0]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        d = {\n",
    "            \"+\": 1,\n",
    "            \"-\": 1,\n",
    "            \"*\": 2,\n",
    "            \"/\": 2\n",
    "        }\n",
    "        operat_stack = []\n",
    "        symbol_stack = []\n",
    "        num = \"\"\n",
    "        for ele in s:\n",
    "            if ele == \" \":\n",
    "                continue\n",
    "            val = d.get(ele, None)\n",
    "            if val:\n",
    "                operat_stack.append(int(num))\n",
    "                num = \"\"\n",
    "                if len(symbol_stack) == 0:\n",
    "                    symbol_stack.append(ele)\n",
    "                else:\n",
    "                    while len(operat_stack) > 1:\n",
    "                        next_val = d.get(symbol_stack[-1])\n",
    "                        if next_val < val:\n",
    "                            break\n",
    "                        right = operat_stack.pop()\n",
    "                        left = operat_stack.pop()\n",
    "                        symbol = symbol_stack.pop()\n",
    "                        res = self.get_result(symbol, left, right)\n",
    "                        operat_stack.append(res)\n",
    "\n",
    "                    symbol_stack.append(ele)\n",
    "            else:\n",
    "                num += ele\n",
    "        operat_stack.append(int(num))\n",
    "\n",
    "        while len(symbol_stack) > 0:\n",
    "            right = operat_stack.pop()\n",
    "            left = operat_stack.pop()\n",
    "            symbol = symbol_stack.pop()\n",
    "            res = self.get_result(symbol, left, right)\n",
    "            operat_stack.append(res)\n",
    "        \n",
    "        res = 0\n",
    "        xi = 1\n",
    "        while len(operat_stack) > 0:\n",
    "            res += xi*operat_stack.pop()\n",
    "            xi *= 10\n",
    "        return res\n",
    "    \n",
    "\n",
    "    def get_result(self, symbol, left, right):\n",
    "        if symbol == \"+\":\n",
    "            return left + right\n",
    "        elif symbol == \"-\":\n",
    "            return left - right\n",
    "        elif symbol == \"*\":\n",
    "            return left * right\n",
    "        elif symbol == \"/\":\n",
    "            return left // right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        hashmap = {'+':1,'-':-1,'*':2,'/':-2}\n",
    "        res = 0\n",
    "        while s:\n",
    "            start = 0\n",
    "            while start < len(s) and s[start] not in hashmap: \n",
    "                start+=1\n",
    "            if start<len(s):\n",
    "                nowcal,nownum = s[start],int(s[:start])\n",
    "                if stack:\n",
    "                    if stack[-1][0]=='*' or stack[-1][0]=='/':\n",
    "                        cal,num = stack.pop()\n",
    "                        if cal =='*': nownum = num*nownum\n",
    "                        else: nownum = num//nownum\n",
    "                    if stack and (nowcal=='+' or nowcal == '-'):\n",
    "                        cal,num=stack.pop()\n",
    "                        if cal=='+':nownum = num+nownum\n",
    "                        else: nownum=num-nownum\n",
    "                    stack.append([nowcal,nownum])\n",
    "                else:\n",
    "                    stack.append([nowcal,int(s[:start])])\n",
    "                s=s[start+1:]\n",
    "            else:\n",
    "                res = int(s)\n",
    "                while stack:\n",
    "                    cal,num = stack.pop()\n",
    "                    if cal=='+': res+=num\n",
    "                    elif cal=='-': res = num-res\n",
    "                    elif cal=='*': res*=num\n",
    "                    else: res = num//res\n",
    "                break\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = ''.join(s.split(' '))\n",
    "        while ('*' in s) | ('/' in s):\n",
    "            for i in range(len(s)):\n",
    "                if s[i] in '*/':\n",
    "                    j = i\n",
    "                    while j > 0:\n",
    "                        j -= 1\n",
    "                        if s[j] not in '1234567890':\n",
    "                            break\n",
    "                    k = i\n",
    "                    while k < len(s)-1:\n",
    "                        k += 1\n",
    "                        if s[k] not in '1234567890':\n",
    "                            break\n",
    "                    if s[i] == '*':\n",
    "                        if (j > 0) & (k < len(s)-1):\n",
    "                            s = s[:(j+1)] + str(int(int(s[(j+1):i] if j+1 < i else 0)*int(s[(i+1):k] if i+1 < k else 0))) + s[k:]\n",
    "                            break\n",
    "                        elif (j == 0) & (k < len(s)-1):\n",
    "                            s = str(int(int(s[:i])*int(s[(i+1):k] if i+1 < k else 0))) + s[k:]\n",
    "                            break\n",
    "                        elif (j > 0) & (k == len(s)-1):\n",
    "                            s = s[:(j+1)] + str(int(int(s[(j+1):i] if j+1 < i else 0)*int(s[(i+1):])))\n",
    "                            break\n",
    "                        elif (j == 0) & (k == len(s)-1):\n",
    "                            s = str(int(int(s[:i])*int(s[(i+1):])))\n",
    "                            break\n",
    "                    elif s[i] == '/':\n",
    "                        if (j > 0) & (k < len(s)-1):\n",
    "                            s = s[:(j+1)] + str(int(int(s[(j+1):i] if j+1 < i else 0)/int(s[(i+1):k] if i+1 < k else 0))) + s[k:]\n",
    "                            break\n",
    "                        elif (j == 0) & (k < len(s)-1):\n",
    "                            s = str(int(int(s[:i])/int(s[(i+1):k] if i+1 < k else 0))) + s[k:]\n",
    "                            break\n",
    "                        elif (j > 0) & (k == len(s)-1):\n",
    "                            s = s[:(j+1)] + str(int(int(s[(j+1):i] if j+1 < i else 0)/int(s[(i+1):])))\n",
    "                            break\n",
    "                        elif (j == 0) & (k == len(s)-1):\n",
    "                            s = str(int(int(s[:i])/int(s[(i+1):])))\n",
    "                            break \n",
    "\n",
    "        \n",
    "        res = 0\n",
    "        s = '+' + s + '+0'\n",
    "        value = ''\n",
    "        sign = '+'\n",
    "        for i in s:\n",
    "            if i in '+-':\n",
    "                res += (int(value) if len(value) > 0 else 0)*(1 if sign == '+' else -1)\n",
    "                sign = i\n",
    "                value = ''\n",
    "            else:\n",
    "                value = value + i\n",
    "        res += (int(value) if len(value) > 0 else 0)*(1 if sign == '+' else -1)\n",
    "        return(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        P = {'+':0,'-':0,'*':1,'/':1}\n",
    "        OP = []\n",
    "        NUM = []\n",
    "        l = len(s)\n",
    "        def cal(a,b,op):\n",
    "            if op == '+':\n",
    "                return a + b\n",
    "            if op == '-':\n",
    "                return a - b\n",
    "            if op == '*':\n",
    "                return a * b\n",
    "            if op == '/':\n",
    "                return a // b\n",
    "        i = 0\n",
    "        while i < l:\n",
    "            c = s[i]\n",
    "            if c == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if c in P:\n",
    "                while len(OP) > 0 and P[OP[-1]] >= P[c]:\n",
    "                    b = NUM.pop()\n",
    "                    a = NUM.pop()\n",
    "                    op = OP.pop()\n",
    "                    NUM.append(cal(a,b,op))\n",
    "                OP.append(c)\n",
    "                i += 1\n",
    "                continue\n",
    "            tmp = 0\n",
    "            while i < l and s[i].isdigit():\n",
    "                tmp = tmp * 10 + ord(s[i]) - ord('0')\n",
    "                i += 1\n",
    "            NUM.append(tmp)\n",
    "\n",
    "        while len(OP) > 0:\n",
    "            b = NUM.pop()\n",
    "            a = NUM.pop()\n",
    "            op = OP.pop()\n",
    "            NUM.append(cal(a,b,op))\n",
    "        return NUM[0]\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def calc(ops, nums):\n",
    "            if not ops or len(nums) <= 1: return\n",
    "\n",
    "            op = ops.pop()\n",
    "            b, a = nums.pop(), nums.pop()\n",
    "            res = 0\n",
    "            if op == '+': res = a + b\n",
    "            elif op == '-': res = a - b\n",
    "            elif op == '*': res = a * b\n",
    "            elif op == '/': res = a // b\n",
    "            else: raise ValueError\n",
    "\n",
    "            nums.append(res)\n",
    "        pr = {\n",
    "            '+': 1, '-': 1,\n",
    "            '*': 2, '/': 2,\n",
    "        }\n",
    "        ops = []\n",
    "        nums = [0]\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            c = s[i]\n",
    "            if c == ' ':\n",
    "                pass\n",
    "            elif c.isdigit():\n",
    "                u = 0\n",
    "                j = i\n",
    "                while j < n and s[j].isdigit():\n",
    "                    u = u * 10 + int(s[j])\n",
    "                    j += 1\n",
    "                i = j - 1\n",
    "                nums.append(u)\n",
    "            else:\n",
    "                while ops and pr[ops[-1]] >= pr[c]:\n",
    "                    calc(ops, nums)\n",
    "                ops.append(c)\n",
    "            i += 1\n",
    "        while ops:\n",
    "            calc(ops, nums)\n",
    "        return nums[-1]\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self.s = s.replace(' ', '')\n",
    "        self.index = 0\n",
    "        return self.expression_value()\n",
    "\n",
    "    def expression_value(self):\n",
    "        a = self.term_value()\n",
    "        while self.index < len(self.s) and self.s[self.index] in '+-':\n",
    "            c = self.s[self.index]\n",
    "            self.index += 1\n",
    "            b = self.term_value()\n",
    "            if c == '+': a += b\n",
    "            else: a -= b\n",
    "        return a\n",
    "\n",
    "    def term_value(self):\n",
    "        a = self.factor_value()\n",
    "        while self.index < len(self.s) and self.s[self.index] in '*/':\n",
    "            c = self.s[self.index]\n",
    "            self.index += 1\n",
    "            b = self.factor_value()\n",
    "            if c == '*': a *= b\n",
    "            else: a //= b\n",
    "        return a\n",
    "\n",
    "    def factor_value(self):\n",
    "        if self.s[self.index] == '-':\n",
    "            self.index += 1\n",
    "            return -self.factor_value()\n",
    "        if self.s[self.index] == '(':\n",
    "            self.index += 1\n",
    "            ans = self.expression_value()\n",
    "            self.index += 1 # assert ')'\n",
    "            return ans\n",
    "        else:\n",
    "            start = self.index\n",
    "            while self.index<len(self.s) and (self.s[self.index].isdigit()) or self.index==start and self.s[self.index]=='-':\n",
    "                self.index += 1\n",
    "            return int(self.s[start:self.index])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import time\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        zero = ord('0')\n",
    "        n = -1\n",
    "        lastop = ''\n",
    "        stacks = []\n",
    "        lastadd = 0\n",
    "\n",
    "        def append(n):\n",
    "            if len(stacks) > 0:\n",
    "                lop = stacks[len(stacks)-1]\n",
    "                if lop == '*':\n",
    "                    stacks.pop()\n",
    "                    n1 = stacks.pop()\n",
    "                    stacks.append(n1*n)\n",
    "                elif lop == '/':\n",
    "                    stacks.pop()\n",
    "                    n1 = stacks.pop()\n",
    "                    stacks.append(int(n1/n))\n",
    "                else:\n",
    "                    stacks.append(n)\n",
    "                    if len(stacks) >= 5:\n",
    "                        n1 = stacks.pop(0)\n",
    "                        op = stacks.pop(0)\n",
    "                        n2 = stacks.pop(0)\n",
    "                        if op == '+':\n",
    "                            stacks.insert(0, n1+n2)\n",
    "                        else:\n",
    "                            stacks.insert(0, n1-n2)\n",
    "\n",
    "            else:\n",
    "                stacks.append(n)\n",
    "\n",
    "        for c in s:\n",
    "            if c == ' ':\n",
    "                continue\n",
    "\n",
    "            dn = ord(c)-zero\n",
    "            if dn >= 0:\n",
    "                if n >= 0:\n",
    "                    n = n*10+dn\n",
    "                else:\n",
    "                    n = dn\n",
    "            else:\n",
    "                if n >= 0:\n",
    "                    append(n)\n",
    "                    n = -1\n",
    "                stacks.append(c)\n",
    "        if n >= 0:\n",
    "            append(n)\n",
    "        \n",
    "        num = stacks.pop(0)\n",
    "        while len(stacks) > 0:\n",
    "            op = stacks.pop(0)\n",
    "            n2 = stacks.pop(0)\n",
    "            if op == '+':\n",
    "                num += n2\n",
    "            else:\n",
    "                num -= n2\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        op = []\n",
    "        nums = []\n",
    "        bos = '#'\n",
    "        eos = '$'\n",
    "        s = s.replace(' ', '')\n",
    "        s = bos + s + eos\n",
    "        priority = {'+': 1, '-': 1, '*': 2, '/': 2, bos: -1, eos: 0}\n",
    "        ops = {'+', '-', '*', '/', bos, eos}\n",
    "        def add(a, b):\n",
    "            return a + b\n",
    "        def sub(a, b):\n",
    "            return a - b\n",
    "        def mul(a, b):\n",
    "            return a * b\n",
    "        def div(a, b):\n",
    "            return a // b \n",
    "        compute = {'+': add, '-': sub, '*': mul, '/': div}\n",
    "        is_last_digit = False\n",
    "        for ch in s:\n",
    "            if ch.isdigit():\n",
    "                num = int(ch)\n",
    "                if is_last_digit:\n",
    "                    last_digit = nums.pop()\n",
    "                    num = last_digit * 10 + num\n",
    "                nums.append(num)\n",
    "                is_last_digit = True\n",
    "            else:\n",
    "                is_last_digit = False\n",
    "                cur_priority = priority[ch]\n",
    "                while len(op) > 0 and priority[op[-1]] >= cur_priority:\n",
    "                    last_op = op.pop()\n",
    "                    if last_op == bos:\n",
    "                        continue\n",
    "                    num_right = nums.pop()\n",
    "                    num_left = nums.pop()\n",
    "                    tmp = compute[last_op](num_left, num_right)\n",
    "                    nums.append(tmp)\n",
    "                op.append(ch)\n",
    "        return nums[-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        res = 0\n",
    "        num = 0\n",
    "        sign = 1\n",
    "        flag = 0\n",
    "        stack = []\n",
    "        for c in s:\n",
    "            # print(res,c)\n",
    "            if c.isdigit():\n",
    "                num = num*10 + int(c)\n",
    "                continue\n",
    "            if c == ' ':\n",
    "                continue\n",
    "            if flag == 1:\n",
    "                num *= tmp\n",
    "                flag=0\n",
    "            if flag == 2:\n",
    "                num = tmp//num\n",
    "                flag = 0\n",
    "            if c in ['+','-']:\n",
    "                res += sign*num\n",
    "                num = 0\n",
    "                if c == '+':\n",
    "                    sign =1\n",
    "                else:\n",
    "                    sign =-1\n",
    "\n",
    "            if c in ['*','/']:\n",
    "                if c == '*':\n",
    "                    flag = 1\n",
    "                else:\n",
    "                    flag = 2\n",
    "                tmp = num\n",
    "                num = 0\n",
    "        if flag == 1:\n",
    "            num *= tmp\n",
    "            flag=0\n",
    "        if flag == 2:\n",
    "            num = tmp//num\n",
    "            flag = 0\n",
    "        res += sign*num\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        priority = {'+': 1, '-': 1, '*': 2, '/': 2}\n",
    "        nums_stack = []\n",
    "        ops_stack = []\n",
    "        nums_stack.append(0)\n",
    "        s = s.replace(\" \", \"\")\n",
    "        length = len(s)\n",
    "        i = 0\n",
    "        while i < length:\n",
    "            if s[i] == '(':\n",
    "                ops_stack.append('(')\n",
    "            elif s[i] == ')':\n",
    "                while len(ops_stack) > 0:\n",
    "                    if ops_stack[-1] == '(':\n",
    "                        ops_stack.pop()\n",
    "                        break\n",
    "                    results = self.cal_top(nums_stack, ops_stack)\n",
    "                    nums_stack.append(results)\n",
    "                    ops_stack.pop()\n",
    "            else:\n",
    "                if '0' <= s[i] <= '9':\n",
    "                    num = 0\n",
    "                    j = i\n",
    "                    while j < length and '0' <= s[j] <= '9':\n",
    "                        num = num * 10 + ord(s[j]) - ord('0')\n",
    "                        j += 1\n",
    "                    nums_stack.append(num)\n",
    "                    i = j - 1\n",
    "                else:\n",
    "                    if i > 0 and (s[i - 1] == '(' or s[i - 1] == '+' or s[i - 1] == '-'):\n",
    "                        nums_stack.append(0)\n",
    "                    while len(ops_stack) > 0 and ops_stack[-1] != '(':\n",
    "                        last_op = ops_stack[-1]\n",
    "                        last_priority = priority[last_op]\n",
    "                        cnt_priority = priority[s[i]]\n",
    "                        if last_priority >= cnt_priority:\n",
    "                            results = self.cal_top(nums_stack, ops_stack)\n",
    "                            nums_stack.append(results)\n",
    "                        else:\n",
    "                            break\n",
    "                    ops_stack.append(s[i])\n",
    "            i += 1\n",
    "        while len(ops_stack) > 0:\n",
    "            results = self.cal_top(nums_stack, ops_stack)\n",
    "            nums_stack.append(results)\n",
    "        return nums_stack[-1]\n",
    "\n",
    "    def cal_top(self, nums_stack, ops_stack):\n",
    "        x1 = nums_stack.pop()\n",
    "        x2 = nums_stack.pop()\n",
    "        cnt_op = ops_stack.pop()\n",
    "        if cnt_op == '+':\n",
    "            return x1 + x2\n",
    "        elif cnt_op == '-':\n",
    "            return x2 - x1\n",
    "        elif cnt_op == '*':\n",
    "            return x1 * x2\n",
    "        else:\n",
    "            return int(x2 / x1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        expression = ''\n",
    "        for ch in s:\n",
    "            if ch and ch != ' ':\n",
    "                expression += ch\n",
    "        n = len(expression)\n",
    "\n",
    "        def help(item):\n",
    "            if len(item) == 1:\n",
    "                return item\n",
    "            while '/' in item or '*' in item:\n",
    "                div = item.find('/')\n",
    "                mul = item.find('*')\n",
    "                if mul == -1 or (div < mul and div != -1):\n",
    "                    l = div\n",
    "                    r = div\n",
    "                    while l > 0 and item[l - 1].isdigit():\n",
    "                        l -= 1\n",
    "                    while r < len(item) - 1 and item[r + 1].isdigit():\n",
    "                        r += 1\n",
    "                    item = item[:l] + str(int(item[l:div]) // int(item[div + 1: r + 1])) + item[r + 1:]\n",
    "                elif div == -1 or (mul < div and mul != -1):\n",
    "                    l = mul\n",
    "                    r = mul\n",
    "                    while l > 0 and item[l - 1].isdigit():\n",
    "                        l -= 1\n",
    "                    while r < len(item) - 1 and item[r + 1].isdigit():\n",
    "                        r += 1\n",
    "                    item = item[:l] + str(int(item[l:mul]) * int(item[mul + 1: r + 1])) + item[r + 1:]\n",
    "            if '-' in item or '+' in item:\n",
    "                result = 0\n",
    "                i = 0\n",
    "                for c in range(len(item)):\n",
    "                    if not item[c].isdigit():\n",
    "                        break\n",
    "                    i += 1\n",
    "                if i > 0:\n",
    "                    result = int(item[:i])\n",
    "                while i < len(item):\n",
    "                    if i < len(item) and item[i] == '-':\n",
    "                        r = i\n",
    "                        while r < len(item) - 1 and item[r + 1].isdigit():\n",
    "                            r += 1\n",
    "                        result -= int(item[i + 1: r + 1])\n",
    "                        i = r + 1\n",
    "                    if i < len(item) and item[i] == '+':\n",
    "                        r = i\n",
    "                        while r < len(item) - 1 and item[r + 1].isdigit():\n",
    "                            r += 1\n",
    "                        result += int(item[i + 1: r + 1])\n",
    "                        i = r + 1\n",
    "                return str(result)\n",
    "\n",
    "            return item\n",
    "        result = help(expression)\n",
    "        return int(result)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def priority(self, c: str) -> int:\n",
    "        if c == '+' or c == '-':\n",
    "            return 1\n",
    "        else:\n",
    "            return 2\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        stackop = []\n",
    "        stacknum = []\n",
    "        num = 0\n",
    "        for c in s:\n",
    "            if c == \" \": continue\n",
    "            if c.isdigit():\n",
    "                num = num * 10 + ord(c) - ord('0')\n",
    "            elif c in '+-*/':\n",
    "                stacknum.append(num)\n",
    "                num = 0\n",
    "                while stackop and self.priority(stackop[-1]) >= self.priority(c):\n",
    "                    op = stackop.pop()\n",
    "                    n2 = stacknum.pop()\n",
    "                    n1 = stacknum.pop()\n",
    "                    if op == '+':\n",
    "                        stacknum.append(n1 + n2)\n",
    "                    elif op == '-':\n",
    "                        stacknum.append(n1 - n2)\n",
    "                    elif op == '*':\n",
    "                        stacknum.append(n1 * n2)\n",
    "                    else:\n",
    "                        stacknum.append(n1 // n2)\n",
    "                stackop.append(c)\n",
    "        stacknum.append(num)\n",
    "        while stackop:\n",
    "            op = stackop.pop()\n",
    "            n2 = stacknum.pop()\n",
    "            n1 = stacknum.pop()\n",
    "            if op == '+':\n",
    "                stacknum.append(n1 + n2)\n",
    "            elif op == '-':\n",
    "                stacknum.append(n1 - n2)\n",
    "            elif op == '*':\n",
    "                stacknum.append(n1 * n2)\n",
    "            else:\n",
    "                stacknum.append(n1 // n2)\n",
    "        return stacknum[0]\n",
    "                \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calc(self, a, b, op):\n",
    "        if op == \"+\":\n",
    "            return a + b\n",
    "        elif op == \"-\":\n",
    "            return a - b\n",
    "        elif op == \"*\":\n",
    "            return a * b\n",
    "        elif op == \"/\":\n",
    "            return int(a / b)\n",
    "    def calculate(self, s: str) -> int:\n",
    "        priority = {\"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "        num_stack, op_stack = [], []\n",
    "        s = s.replace(\" \", \"\")\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i].isdigit():\n",
    "                j = i \n",
    "                while i + 1 < n and s[i+1].isdigit():\n",
    "                    i += 1\n",
    "                num_stack.append(int(s[j:i+1]))\n",
    "            else:\n",
    "                while op_stack and priority[op_stack[-1]] >= priority[s[i]]:\n",
    "                    b = num_stack.pop()\n",
    "                    a = num_stack.pop()\n",
    "                    op = op_stack.pop()\n",
    "                    res = self.calc(a, b, op)\n",
    "                    num_stack.append(res)\n",
    "                op_stack.append(s[i])\n",
    "            i += 1\n",
    "        while op_stack:\n",
    "            b = num_stack.pop()\n",
    "            a = num_stack.pop()\n",
    "            op = op_stack.pop()\n",
    "            res = self.calc(a, b, op)\n",
    "            num_stack.append(res)\n",
    "        return num_stack[-1]\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        symbol, symbol_mul = '+', '*'\n",
    "        result, result1 = 0, 1\n",
    "        recent_num, recent_num1 = '', ''\n",
    "        for i in range(len(s)):\n",
    "            if s[i] == ' ':\n",
    "                pass\n",
    "            elif s[i] not in ['-', '+']:\n",
    "                if s[i].isdigit():\n",
    "                    recent_num1 += s[i]\n",
    "                else:\n",
    "                    if symbol_mul == \"*\":\n",
    "                        result1 *= int(recent_num1)\n",
    "                    elif symbol_mul == '/':\n",
    "                        result1 //= int(recent_num1)\n",
    "                    symbol_mul = s[i]\n",
    "                    recent_num1 = ''\n",
    "    \n",
    "    \n",
    "            else:\n",
    "                if symbol_mul == \"*\":\n",
    "                    result1 *= int(recent_num1)\n",
    "                elif symbol_mul == '/':\n",
    "                    result1 //= int(recent_num1)\n",
    "                symbol_mul = '*'\n",
    "                recent_num1 = ''\n",
    "                recent_num = result1\n",
    "                result1 = 1\n",
    "                if symbol == \"+\":\n",
    "                    result += recent_num\n",
    "                elif symbol == '-':\n",
    "                    result -= recent_num\n",
    "                symbol = s[i]\n",
    "                recent_num = ''\n",
    "                print(result)\n",
    "            if i == len(s) - 1:\n",
    "                if symbol_mul == \"*\":\n",
    "                    result1 *= int(recent_num1)\n",
    "                elif symbol_mul == '/':\n",
    "                    result1 //= int(recent_num1)\n",
    "                symbol_mul = '*'\n",
    "                recent_num1 = ''\n",
    "                recent_num = result1\n",
    "                result1 = 1\n",
    "                if symbol == \"+\":\n",
    "                    result += recent_num\n",
    "                elif symbol == '-':\n",
    "                    result -= recent_num\n",
    "                print(result)\n",
    "        return int(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = \"\".join(s.split())\n",
    "        while '*' in s or '/' in s:\n",
    "            obj = 0\n",
    "            right_right = 0\n",
    "            right_left = 0\n",
    "            left_right = 0\n",
    "            left_left = 0\n",
    "            while obj < len(s) and s[obj] != '*' and s[obj] != '/':\n",
    "                obj += 1\n",
    "            left_right = obj\n",
    "            left_left = obj - 1\n",
    "            right_left = obj+1\n",
    "            right_right = obj+2\n",
    "            while s[left_left].isdigit() and left_left>-1:\n",
    "                left_left = left_left -1\n",
    "            while right_right<= len(s)-1 and s[right_right].isdigit():\n",
    "                right_right= right_right+1\n",
    "            if s[obj] == '*':\n",
    "                s = s[0: left_left+1] + str(int(s[left_left+1: left_right]) * int(s[right_left: right_right])) + s[right_right:]\n",
    "            else:\n",
    "                s = s[0: left_left+1] + str(int(s[left_left+1: left_right]) // int(s[right_left: right_right])) + s[right_right:]\n",
    "\n",
    "        \n",
    "\n",
    "        while '+' in s or '-' in s:\n",
    "            if s[0] == '-':\n",
    "                if '+' in s[1:] or '-' in s[1:]:\n",
    "                    print('start')\n",
    "                    obj = 1\n",
    "                    right_right = 0\n",
    "                    right_left = 0\n",
    "                    left_right = 0\n",
    "                    left_left = 0\n",
    "                    while obj < len(s) and s[obj] != '+' and s[obj] != '-':\n",
    "                        obj += 1\n",
    "                    left_right = obj\n",
    "                    left_left = obj - 1\n",
    "                    right_left = obj+1\n",
    "                    right_right = obj+2\n",
    "                    while s[left_left].isdigit() and left_left>-1:\n",
    "                        left_left = left_left -1\n",
    "                    while right_right<= len(s)-1 and s[right_right].isdigit():\n",
    "                        right_right= right_right+1\n",
    "                    if s[obj] == '+':\n",
    "                        s = str(int(s[left_left+1: left_right])*(-1) + int(s[right_left: right_right])) + s[right_right:]\n",
    "                    else:\n",
    "                        s =  str(int(s[left_left+1: left_right])*(-1) - int(s[right_left: right_right])) + s[right_right:]\n",
    "                else: return(int(s))\n",
    "            else:\n",
    "                obj = 0\n",
    "                right_right = 0\n",
    "                right_left = 0\n",
    "                left_right = 0\n",
    "                left_left = 0\n",
    "                while obj < len(s) and s[obj] != '+' and s[obj] != '-':\n",
    "                    obj += 1\n",
    "                left_right = obj\n",
    "                left_left = obj - 1\n",
    "                right_left = obj+1\n",
    "                right_right = obj+2\n",
    "                while s[left_left].isdigit() and left_left>-1:\n",
    "                    left_left = left_left -1\n",
    "                while right_right<= len(s)-1 and s[right_right].isdigit():\n",
    "                    right_right= right_right+1\n",
    "                if s[obj] == '+':\n",
    "                    s = s[0: left_left+1] + str(int(s[left_left+1: left_right]) + int(s[right_left: right_right])) + s[right_right:]\n",
    "                else:\n",
    "                    s = s[0: left_left+1] + str(int(s[left_left+1: left_right]) - int(s[right_left: right_right])) + s[right_right:]\n",
    "\n",
    "\n",
    "\n",
    "        return (int(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        size = len(s)\n",
    "        stack = []\n",
    "        op = '+'\n",
    "        index = 0\n",
    "        while index < size:\n",
    "            if s[index] == ' ':\n",
    "                index += 1\n",
    "                continue\n",
    "            if s[index].isdigit():\n",
    "                print(\"s[index]:\",s[index])\n",
    "                #num = ord(s[index]) - ord('0')\n",
    "                num = int(s[index])\n",
    "                while index + 1 < size and s[index+1].isdigit():\n",
    "                    index += 1\n",
    "                    #num = 10 * num + ord(s[index]) - ord('0')\n",
    "                    num = 10 * num + int(s[index])\n",
    "                if op == '+':\n",
    "                    stack.append(num)\n",
    "                elif op == '-':\n",
    "                    stack.append(-num)\n",
    "                elif op == '*':\n",
    "                    top = stack.pop()\n",
    "                    stack.append(top * num)\n",
    "                elif op == '/':\n",
    "                    top = stack.pop()\n",
    "                    stack.append(int(top / num))\n",
    "            elif s[index] in \"+-*/\":\n",
    "                op = s[index]\n",
    "            index += 1\n",
    "        return sum(stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = collections.deque()\n",
    "        s = s.strip()\n",
    "        n = len(s)\n",
    "        signs = [\"+\", \"-\", \"*\", \"/\"]\n",
    "        sign = \"+\"\n",
    "        num = 0\n",
    "        for i, elem in enumerate(s):\n",
    "            if elem == \" \":\n",
    "                continue\n",
    "            if \"0\" <= elem <= \"9\":\n",
    "                num = num * 10 + int(elem)\n",
    "            if i == (n-1) or elem in signs:\n",
    "                if sign == \"+\":\n",
    "                    stack.append(num)\n",
    "                elif sign == \"-\":\n",
    "                    stack.append(-num)\n",
    "                elif sign == \"*\":\n",
    "                    stack.append(stack.pop() * num)\n",
    "                else:\n",
    "                    stack.append(int(stack.pop() / num))\n",
    "                sign = elem\n",
    "                num = 0\n",
    "        \n",
    "        return sum(stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        num = 0\n",
    "        ans = 0\n",
    "        stack = []\n",
    "        preSign = \"+\"\n",
    "        for i, c in enumerate(s):\n",
    "            if c.isdigit():\n",
    "                num = 10*num+int(c)\n",
    "            if c in '+-*/' or i==len(s)-1:\n",
    "                if preSign=='*':\n",
    "                    t = stack.pop()\n",
    "                    num = num*t\n",
    "                    stack.append(num)\n",
    "                elif preSign=='/':\n",
    "                    t = stack.pop()\n",
    "                    num = int(t/num)\n",
    "                    stack.append(num)\n",
    "                elif preSign=='+':\n",
    "                    stack.append(num)\n",
    "                elif preSign=='-':\n",
    "                    stack.append(-num)\n",
    "                preSign = c\n",
    "                num = 0\n",
    "        while stack:\n",
    "            ans += stack.pop()\n",
    "        return ans\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        string = s\n",
    "        # split the string\n",
    "        h = []\n",
    "        cur = ''\n",
    "        sign = None\n",
    "        for i, s in enumerate(string):\n",
    "            if s.isdigit():\n",
    "                cur += s\n",
    "            if i == len(string)-1 or s in ['+', '-', '*','/']:\n",
    "                if sign == '*':\n",
    "                    cur = h.pop() * int(cur)\n",
    "                elif sign == '/':\n",
    "                    cur = int(h.pop() / int(cur))\n",
    "                elif sign == '+':\n",
    "                    cur = int(cur)\n",
    "                elif sign == '-':\n",
    "                    cur = -int(cur)\n",
    "                else:\n",
    "                    cur = int(cur)\n",
    "                h.append(int(cur))\n",
    "                sign = s \n",
    "                cur = ''\n",
    "\n",
    "        return sum(h)\n",
    "        #return int(h3[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        n = len(s)\n",
    "        stack = []\n",
    "        pre_sign = '+'\n",
    "        num = 0\n",
    "        for i in range(n):\n",
    "            if s[i] != ' ' and s[i].isdigit():\n",
    "                num = num * 10 + ord(s[i]) - ord('0')\n",
    "            \n",
    "            if i == n - 1 or s[i] in '+-*/':\n",
    "                if pre_sign == '+':\n",
    "                    stack.append(num)\n",
    "                elif pre_sign == '-':\n",
    "                    stack.append(-num)\n",
    "                elif pre_sign == \"*\":\n",
    "                    stack.append(stack.pop() * num)\n",
    "                else:\n",
    "                    stack.append(int(stack.pop() / num))\n",
    "                pre_sign = s[i]\n",
    "                num = 0\n",
    "        \n",
    "        return sum(stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        stack = []\n",
    "        sign = '+'\n",
    "        num = 0\n",
    "        for i in range(n):\n",
    "            if s[i] != ' ' and s[i].isdigit():\n",
    "                num = num * 10 + ord(s[i]) - ord('0') # 存在超过10的数字\n",
    "            if i == n - 1 or s[i] in '+-*/':\n",
    "                if sign == '+':\n",
    "                    stack.append(num)\n",
    "                elif sign == '-':\n",
    "                    stack.append(-num)\n",
    "                elif sign == '*':\n",
    "                    stack.append(stack.pop() * num)\n",
    "                else:\n",
    "                    stack.append(int(stack.pop() / num))\n",
    "                sign = s[i]\n",
    "                num = 0\n",
    "        return sum(stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s_l):\n",
    "            cal_stack = []\n",
    "            num = 0\n",
    "            ops = \"+\"\n",
    "            while s_l:\n",
    "                c = s_l.popleft()\n",
    "                if 0<=ord(c)-ord(\"0\")<=9:\n",
    "                    num = num*10+ord(c)-ord(\"0\")\n",
    "                if c in [\"+\", \"-\", \"*\", \"/\"] or len(s_l)==0:\n",
    "                    if ops in [\"+\", \"-\"]:\n",
    "                        if ops == \"-\":\n",
    "                            num *= -1\n",
    "                    else:\n",
    "                        prev = cal_stack.pop()\n",
    "                        if ops == \"*\":\n",
    "                            num = prev * num\n",
    "                        else:\n",
    "                            num = int(prev / num)\n",
    "                    cal_stack.append(num)\n",
    "                    num = 0\n",
    "                    ops = c\n",
    "            \n",
    "            return sum(cal_stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        num_stack = []\n",
    "        op_stack = []\n",
    "        cur = None\n",
    "        s = s + '+'\n",
    "        for i in s:\n",
    "            if i == ' ':\n",
    "                continue\n",
    "            else:\n",
    "                if i in '0123456789':\n",
    "                    if cur is None:\n",
    "                        cur = ord(i) - ord('0')\n",
    "                    else:\n",
    "                        cur = cur*10 + ord(i) - ord('0')\n",
    "                else:\n",
    "                    if op_stack and op_stack[-1] in '*/': \n",
    "                        a = num_stack.pop()\n",
    "                        o = op_stack.pop()\n",
    "                        num_stack.append(self.domath(a, cur, o))\n",
    "                    else:\n",
    "                        num_stack.append(cur)\n",
    "                    op_stack.append(i)\n",
    "                    cur = None\n",
    "        if cur is not None:\n",
    "            num_stack.append(cur)\n",
    "            cur = None\n",
    "        s1 = []\n",
    "        s2 = []\n",
    "        while num_stack:\n",
    "            s1.append(num_stack.pop())\n",
    "            s2.append(op_stack.pop())\n",
    "        a = s1.pop()\n",
    "        while s1:\n",
    "            b = s1.pop()\n",
    "            o = s2.pop()\n",
    "            a = self.domath(a, b, o)\n",
    "        return a\n",
    "\n",
    "\n",
    "\n",
    "    def domath(self, a, b, o):\n",
    "        if o == \"+\":\n",
    "            return a+b\n",
    "        elif o == '-':\n",
    "            return a-b\n",
    "        elif o == '*':\n",
    "            return a*b\n",
    "        elif o == '/':\n",
    "            if a/b >= 0:\n",
    "                return a//b\n",
    "            else:\n",
    "                return (a//b)+1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s1 = []\n",
    "        s2 = []\n",
    "        \n",
    "        flag = 0\n",
    "        k = \"\"\n",
    "        temp = 0\n",
    "        n1 = 0\n",
    "        n2 = 0\n",
    "        \n",
    "\n",
    "        cul1 = ['+','-']\n",
    "        cul2 = ['*','/']\n",
    "        i = 0\n",
    "        n = len(s)\n",
    "\n",
    "\n",
    "        while i < n:\n",
    "            if s[i] >='0' and s[i] <='9':\n",
    "                num = 0\n",
    "                i_pro = i\n",
    "                while i_pro<n and s[i_pro] >='0' and s[i_pro] <='9':\n",
    "                    num =num*10 + int(s[i_pro])\n",
    "                    i_pro +=1\n",
    "                i = i_pro-1\n",
    "\n",
    "                if flag == 0:\n",
    "                    s1.append(num)\n",
    "                else:\n",
    "                    flag = 0\n",
    "                    n1 = s1.pop()\n",
    "                    n2 = num\n",
    "\n",
    "                    if k=='*':\n",
    "                        temp = n1*n2\n",
    "                    else :\n",
    "                        temp = int(n1/n2)\n",
    "\n",
    "                    s1.append(temp)\n",
    "                \n",
    "\n",
    "            elif s[i] in cul2:\n",
    "                flag = 1\n",
    "                k = s[i]\n",
    "                \n",
    "            elif s[i] in cul1:\n",
    "                s2.append(s[i])\n",
    "\n",
    "            i +=1\n",
    "\n",
    "\n",
    "        print(s1)\n",
    "        print(s2)\n",
    "        ans = 0 \n",
    "        for i in range(len(s2)-1,-1,-1):\n",
    "            if s2[i] == '+':\n",
    "                n1 = s1.pop()\n",
    "                \n",
    "                ans += n1\n",
    "            else:\n",
    "                n1 = s1.pop()\n",
    "                ans -= n1\n",
    "\n",
    "            \n",
    "\n",
    "        print(ans)\n",
    "        print(s1[0])\n",
    "        return s1[0] + ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        data=[]\n",
    "        signs=['+']\n",
    "        res=0\n",
    "        digit=0\n",
    "        for i in range(len(s)):\n",
    "            if not s[i].isdigit() and s[i]!=' ':\n",
    "                data.append(digit)\n",
    "                digit=0\n",
    "                if signs[-1] in ['*','/']:\n",
    "                    sign=signs.pop()\n",
    "                    d2=data.pop()\n",
    "                    d1=data.pop()\n",
    "                    if sign=='*':\n",
    "                        data.append(d1*d2)\n",
    "                    else:\n",
    "                        data.append(d1//d2)\n",
    "                signs.append(s[i])\n",
    "            elif s[i].isdigit():\n",
    "                digit=10*digit+(ord(s[i])-ord('0'))\n",
    "                # print(digit)\n",
    "        data.append(digit)\n",
    "        if signs[-1] in ['*','/']:\n",
    "            sign=signs.pop()\n",
    "            d2=data.pop()\n",
    "            d1=data.pop()\n",
    "            if sign=='*':\n",
    "                data.append(d1*d2)\n",
    "            else:\n",
    "                data.append(d1//d2)\n",
    "        # print(signs)\n",
    "        # print(data)\n",
    "        for i in range(len(signs)):\n",
    "            if signs[i]=='+':\n",
    "                res+=data[i]\n",
    "            else:\n",
    "                res-=data[i]\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self.where = 0\n",
    "        self.nums_set = set(map(str, range(10)))\n",
    "        def f(s):\n",
    "            cur = 0\n",
    "            num_stack = []\n",
    "            sign_stack = []\n",
    "            while self.where!=len(s) and s[self.where]!=')':\n",
    "                if s[self.where] in self.nums_set:\n",
    "                    cur = cur*10 + int(s[self.where])\n",
    "                elif s[self.where]=='(':\n",
    "                    self.where += 1\n",
    "                    push(s, '', sign_stack, f(s), num_stack)\n",
    "                elif s[self.where] in ('+','-','*','/'):\n",
    "                    push(s, s[self.where], sign_stack, cur, num_stack)\n",
    "                    cur = 0\n",
    "                self.where += 1\n",
    "            push(s, '', sign_stack, cur, num_stack)\n",
    "            return cal(num_stack, sign_stack)\n",
    "\n",
    "        def push(s, sign, sign_stack, num, num_stack):\n",
    "            if len(sign_stack)>0 and sign_stack[-1] in ('*', '/'):\n",
    "                num1 = num_stack.pop()\n",
    "                sign1 = sign_stack.pop()\n",
    "                if sign1=='*':\n",
    "                    num = num1*num\n",
    "                else:\n",
    "                    num = num1//num\n",
    "            num_stack.append(num)\n",
    "            if sign!='':\n",
    "                sign_stack.append(sign)\n",
    "            \n",
    "        \n",
    "        def cal(num_stack, sign_stack):\n",
    "            ans = num_stack[0]\n",
    "            for i in range(len(sign_stack)):\n",
    "                if sign_stack[i]=='+':\n",
    "                    ans += num_stack[i+1]\n",
    "                elif sign_stack[i]=='-':\n",
    "                    ans -= num_stack[i+1]\n",
    "                elif sign_stack[i]=='*':\n",
    "                    ans *= num_stack[i+1]\n",
    "                else:\n",
    "                    ans //= num_stack[i+1]\n",
    "            return ans\n",
    "        return f(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, words: str) -> int:\n",
    "        queue1=[]\n",
    "         \n",
    "        words=words.replace(\" \",\"\")\n",
    "        for w in words:\n",
    "            if w.isdigit():\n",
    "                if len(queue1)>0 and str(queue1[-1]).isdigit():\n",
    "                    lw=queue1.pop()    \n",
    "                    queue1.append(lw*10+int(w))\n",
    "                else:\n",
    "                    queue1.append(int(w))\n",
    "            elif w in [\"+\",\"-\",\"*\",\"/\"]:\n",
    "                queue1.append(w)\n",
    "        nums=[]\n",
    "        ops=[]\n",
    "        n=len(queue1)\n",
    "        print(queue1)\n",
    "        def eval(nums,ops):\n",
    "            second=nums.pop()\n",
    "            first=nums.pop()\n",
    "            typ=ops.pop()\n",
    "            if typ==\"*\":\n",
    "                nums.append(first*second)\n",
    "            elif typ==\"/\":\n",
    "                nums.append(first//second)\n",
    "            elif typ==\"+\":\n",
    "                nums.append(first+second)\n",
    "            elif typ==\"-\":\n",
    "                nums.append(first-second)\n",
    "            return nums,ops\n",
    "        \n",
    "        for i in range(n):\n",
    "            w=queue1[i]\n",
    "            if w not in [\"+\",\"-\",\"*\",\"/\"]:\n",
    "                nums.append(w)\n",
    "            else:\n",
    "                if len(ops)==0:\n",
    "                    ops.append(w)\n",
    "                    continue\n",
    "                if  ops[-1] in [\"*\",\"/\"]:\n",
    "                    nums,ops=eval(nums,ops)\n",
    "                while ((w in [\"+\",\"-\"])  and len(ops)>0 and ops[-1] in [\"+\",\"-\",\"*\",\"/\"]):\n",
    "                    nums,ops=eval(nums,ops)\n",
    "                \n",
    "                ops.append(w)\n",
    "\n",
    "                \n",
    "            \n",
    "\n",
    "        while len(ops)>0:\n",
    "            nums,ops=eval(nums,ops)\n",
    "\n",
    "        return nums[-1]\n",
    "\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, words: str) -> int:\n",
    "        queue1=[]\n",
    "         \n",
    "        words=words.replace(\" \",\"\")\n",
    "        for w in words:\n",
    "            if w.isdigit():\n",
    "                if len(queue1)>0 and str(queue1[-1]).isdigit():\n",
    "                    lw=queue1.pop()    \n",
    "                    queue1.append(lw*10+int(w))\n",
    "                else:\n",
    "                    queue1.append(int(w))\n",
    "            elif w in [\"+\",\"-\",\"*\",\"/\"]:\n",
    "                queue1.append(w)\n",
    "        nums=[]\n",
    "        ops=[]\n",
    "        n=len(queue1)\n",
    "        print(queue1)\n",
    "        def eval(nums,ops):\n",
    "            second=nums.pop()\n",
    "            first=nums.pop()\n",
    "            typ=ops.pop()\n",
    "            if typ==\"*\":\n",
    "                nums.append(first*second)\n",
    "            elif typ==\"/\":\n",
    "                nums.append(first//second)\n",
    "            elif typ==\"+\":\n",
    "                nums.append(first+second)\n",
    "            elif typ==\"-\":\n",
    "                nums.append(first-second)\n",
    "            return nums,ops\n",
    "        \n",
    "        for i in range(n):\n",
    "            w=queue1[i]\n",
    "            if w not in [\"+\",\"-\",\"*\",\"/\"]:\n",
    "                nums.append(w)\n",
    "                if len(ops)>0 and ops[-1] in [\"*\",\"/\"]:\n",
    "                    nums,ops=eval(nums,ops)\n",
    "                 \n",
    "            else:\n",
    "                if len(ops)==0:\n",
    "                    ops.append(w)\n",
    "                    continue\n",
    "                # if  ops[-1] in [\"*\",\"/\"]:\n",
    "                #     nums,ops=eval(nums,ops)\n",
    "                if ((w in [\"+\",\"-\"])  and len(ops)>0 and ops[-1] in [\"+\",\"-\",\"*\",\"/\"]):\n",
    "                    nums,ops=eval(nums,ops)   \n",
    "                ops.append(w)\n",
    "        print(nums,ops)\n",
    "        while len(ops)>0:\n",
    "            nums,ops=eval(nums,ops)\n",
    "\n",
    "        return nums[-1]\n",
    "\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        lis = []\n",
    "        sign = '+'\n",
    "        val = 0\n",
    "        s = list(s)[::-1]\n",
    "        def is_num(x):\n",
    "            for i in range(10):\n",
    "                if x==str(i):\n",
    "                    return True\n",
    "            return False\n",
    "        while s:\n",
    "            ele = s.pop()\n",
    "            if is_num(ele):\n",
    "                val = val*10+int(ele)\n",
    "            if (not is_num(ele) and ele!=' ') or len(s)==0 : #空格无效，最后一个元素也要进栈\n",
    "                if sign=='+':\n",
    "                    lis.append(val)\n",
    "                elif sign=='-':\n",
    "                    lis.append(-1*val)\n",
    "                elif sign=='*':\n",
    "                    lis[-1]*=val\n",
    "                elif sign=='/':\n",
    "                    lis[-1] = int(lis[-1]/val) #注意取整数的方式\n",
    "                val = 0\n",
    "                sign = ele\n",
    "        return sum(lis)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = re.findall(r\"\\d+|.\", s.replace(\" \",\"\"))\n",
    "        fir_ele = int(s[0])\n",
    "        element = [fir_ele]\n",
    "        for i in range(1, len(s)):\n",
    "            if s[i].isdigit():\n",
    "                if s[i-1] == \"-\":\n",
    "                    element.append(-int(s[i]))\n",
    "                elif s[i-1] == \"*\":\n",
    "                    tmpres = int(element.pop())*int(s[i])\n",
    "                    element.append(tmpres)\n",
    "                elif s[i-1] == \"/\":\n",
    "                    tmpres = int(element.pop())/int(s[i])\n",
    "                    element.append(int(tmpres))\n",
    "                else: \n",
    "                    element.append(int(s[i]))\n",
    "        res = sum(element)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        string = s\n",
    "        # split the string\n",
    "        h = []\n",
    "        cur = ''\n",
    "        for s in string:\n",
    "            if s.isdigit():\n",
    "                cur += s\n",
    "            elif s in ['+', '-', '*','/']:\n",
    "                h.append(cur)\n",
    "                h.append(s)\n",
    "                cur = ''\n",
    "            else:\n",
    "                continue\n",
    "        h.append(cur)\n",
    "        print(h)\n",
    "        # perform */ calculation\n",
    "        def calculator(h, operation):\n",
    "            h2 = []\n",
    "            i = 0\n",
    "            while i < len(h):\n",
    "                if h[i] in operation:\n",
    "                    left = h2.pop()\n",
    "                    right = h[i+1]\n",
    "                    if h[i] == '*':\n",
    "                        cur = int(left) * int(right)\n",
    "                    elif h[i] == '/':\n",
    "                        cur = int(left) // int(right)\n",
    "                    elif h[i] == '+':\n",
    "                        cur = int(left) + int(right)\n",
    "                    else:\n",
    "                        cur = int(left) - int(right)\n",
    "                    i += 1\n",
    "                    h2.append(cur)\n",
    "                else:\n",
    "                    h2.append(h[i])\n",
    "                i += 1\n",
    "            return h2\n",
    "    \n",
    "        h2 = calculator(h, ['*', '/'])\n",
    "        h3 = calculator(h2, ['+', '-'])\n",
    "        return int(h3[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # 先乘除后加减\n",
    "        def cal_res(s1,s2,flag):\n",
    "            if(flag == \"+\"):\n",
    "                return int(int(s1) + int(s2))\n",
    "            elif(flag == \"-\"):\n",
    "                return int(int(s1) - int(s2))\n",
    "            elif(flag == \"*\"):\n",
    "                return int(int(s1) * int(s2))\n",
    "            elif(flag == \"/\"):\n",
    "                return int(int(s1) / int(s2))\n",
    "        flag_set = set([\"+\",\"-\",\"*\",\"/\",\"~\"])\n",
    "        stack = []\n",
    "        cal_flag = False\n",
    "        s = s + \"~\"\n",
    "        for char in s:\n",
    "            if(char not in flag_set):\n",
    "                stack.append(char)\n",
    "                continue\n",
    "            else:\n",
    "                nums = []\n",
    "                while(stack and stack[-1] not in flag_set):\n",
    "                    nums.append(stack.pop())\n",
    "                num = \"\".join(nums[::-1])\n",
    "                stack.append(num)\n",
    "                if(cal_flag):\n",
    "                    num2 = stack.pop()\n",
    "                    flag = stack.pop()\n",
    "                    num1 = stack.pop()\n",
    "                    stack.append(str(cal_res(num1,num2,flag)))\n",
    "                stack.append(char)\n",
    "                if(char in (\"*\",\"/\")):\n",
    "                    cal_flag = True\n",
    "                else:\n",
    "                    cal_flag = False\n",
    "        print(stack)\n",
    "        stack.pop()\n",
    "        res = 0\n",
    "        cal_eles = []\n",
    "        for i in range(len(stack)):\n",
    "            cal_eles.append(stack[i])\n",
    "            if(len(cal_eles) == 3):\n",
    "                now_res = cal_res(cal_eles[0],cal_eles[2],cal_eles[1])\n",
    "                cal_eles = []\n",
    "                cal_eles.append(now_res)\n",
    "        return int(cal_eles[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        cur = ''\n",
    "        for s_i in s:\n",
    "            if s_i in ('+', '-', '*', '/'):\n",
    "                if len(cur) > 0:\n",
    "                    stack.append(int(cur))\n",
    "                cur = ''\n",
    "                stack.append(s_i)\n",
    "            else:\n",
    "                cur += s_i\n",
    "\n",
    "        if len(cur) > 0:\n",
    "            stack.append(int(cur))\n",
    "        cur = ''\n",
    "\n",
    "        nums = []\n",
    "        ops  = []\n",
    "\n",
    "        print('stack = ', stack)\n",
    "\n",
    "        for s_i in stack:\n",
    "            if  type(s_i) == str:\n",
    "                ops.append(s_i)\n",
    "            else:\n",
    "                if len(ops) > 0 and ops[-1] in ('*', '/'):\n",
    "                    last_num = nums.pop()\n",
    "                    last_op = ops.pop()\n",
    "                    if last_op == '*':\n",
    "                        s_i *= last_num\n",
    "                    else:\n",
    "                        s_i = int(last_num / s_i)\n",
    "                nums.append(s_i)\n",
    "\n",
    "        print('nums = ', nums)\n",
    "        print('ops = ', ops)\n",
    "\n",
    "        start_num = nums[0]\n",
    "        for i in range(len(ops)):\n",
    "            last_num = nums[i+1]\n",
    "            last_op = ops[i]\n",
    "\n",
    "            if last_op == '+':\n",
    "                start_num = start_num + last_num\n",
    "            else:\n",
    "                start_num = start_num - last_num\n",
    "\n",
    "        return start_num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # 没有括号\n",
    "        # 先把乘除算掉，题目要求每次乘除都取整\n",
    "\n",
    "        # 我的方法，逐个读取，栈，每次遇到加减号就处理前面的乘除\n",
    "        s=s.strip(' ')\n",
    "        s='0'+s if s.startswith('-') else '0+'+s\n",
    "        s=s+'+'  # 让所有乘除都处理掉\n",
    "        total_stack=[]\n",
    "\n",
    "        def part_calculate(input_stack):\n",
    "            # 这里面只包含连续的乘除，返回乘除的结果\n",
    "            i=0\n",
    "            last_position=-1    # 上一个操作符的下标\n",
    "            last_operator=''\n",
    "            ans=None\n",
    "            stack=input_stack.copy()+['*']\n",
    "            while i<len(stack):\n",
    "                while stack[i] not in ['*','/']:i+=1\n",
    "                new_num=int(''.join(stack[last_position+1:i]))\n",
    "                if last_position==-1:\n",
    "                    ans=new_num\n",
    "                else:\n",
    "                    if last_operator=='*':ans*=new_num\n",
    "                    else:ans/=new_num\n",
    "                    ans=int(ans)\n",
    "                last_position=i\n",
    "                last_operator=stack[i]\n",
    "                i+=1\n",
    "            # 加符号以列表形式返回\n",
    "            return list(str(ans)) if ans<0 else list('+'+str(ans))\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            if s[i]==' ':continue\n",
    "            elif s[i].isdigit():total_stack.append(s[i])\n",
    "            elif s[i] in ['*','/']:total_stack.append(s[i])\n",
    "            else:\n",
    "                # 遇到加减号，处理前面的乘除\n",
    "                # 找到上一个加减号位置\n",
    "                idx=len(total_stack)-1\n",
    "                while idx>=0 and total_stack[idx] not in ['+','-']:idx-=1\n",
    "                tmp_stack=total_stack[idx+1:]\n",
    "                if '*' in tmp_stack or '/' in tmp_stack:\n",
    "                    # 前面有乘除\n",
    "                    new_term=part_calculate(tmp_stack)\n",
    "                    # 记得把乘除的结果加上，改符号\n",
    "                    if total_stack[idx]=='-':\n",
    "                        if new_term[0]=='+':new_term[0]='-'\n",
    "                        else:new_term[0]='+'\n",
    "                    # 处理完记得加上符号\n",
    "                    total_stack=total_stack[0:idx]+new_term+[s[i]]\n",
    "                else:total_stack+=[s[i]]\n",
    "\n",
    "        # 下面处理仅加法的stack\n",
    "        # 形式为0+s+\n",
    "        new_s=total_stack\n",
    "        ans=0\n",
    "        i=0\n",
    "        j=0\n",
    "        while i<len(new_s):\n",
    "            while i<len(new_s) and new_s[i].isdigit():i+=1\n",
    "            # i位置为下一个操作符\n",
    "            ans+=int(''.join(new_s[j:i]))\n",
    "            j=i\n",
    "            i+=1\n",
    "        return ans \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        l1, o1 = 0, 1 # 1 for +, -1 for -1\n",
    "        l2, o2 = 1, 1 # 1 for *, -1 for /\n",
    "        idx = 0\n",
    "        # s = ''.join(list(filter(lambda c : c != ' ', s))) #remove all spaces\n",
    "        last = '('\n",
    "        while idx < len(s):                        \n",
    "            if s[idx].isdigit():\n",
    "                num = int(s[idx])\n",
    "                while idx+1 < len(s) and s[idx+1].isdigit():\n",
    "                    idx += 1\n",
    "                    num = num * 10 + int(s[idx])\n",
    "                l2 = l2 * num if o2==1 else int(l2/num)\n",
    "            elif s[idx] == '(':\n",
    "                stack += [l1, o1, l2, o2]\n",
    "                l1, o1 = 0, 1\n",
    "                l2, o2 = 1, 1                \n",
    "            elif s[idx] == ')':\n",
    "                num = l1 + o1*l2\n",
    "                o2, l2 = stack.pop(), stack.pop()\n",
    "                o1, l1 = stack.pop(), stack.pop()\n",
    "                l2 = l2 * num if o2 == 1 else int(l2/num)\n",
    "            elif s[idx] in '+-':                \n",
    "                if idx > 0 and last != '(': # - can be negative sign\n",
    "                    l1 = l1 + o1*l2\n",
    "                o1 = 1 if s[idx] == '+' else -1\n",
    "                l2, o2 = 1, 1\n",
    "            elif s[idx] in '*/':\n",
    "                o2 = 1 if s[idx] == '*' else -1\n",
    "            if s[idx] != ' ':\n",
    "                last = s[idx]\n",
    "            idx += 1\n",
    "        return l1 + o1*l2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack =[]\n",
    "        num =0\n",
    "        op = '+'\n",
    "\n",
    "        def helper(op,num):\n",
    "            if op == '+':\n",
    "                stack.append(num)\n",
    "            elif op == '-':\n",
    "                stack.append(-num)\n",
    "            elif op == '*':\n",
    "                stack.append(stack.pop() * num)\n",
    "            elif op == '/':\n",
    "                stack.append(int(stack.pop() / num))\n",
    "        \n",
    "        for i in range(len(s)):\n",
    "            if s[i].isdigit():\n",
    "                num = 10*num + int(s[i])\n",
    "            \n",
    "            elif s[i] == '(':\n",
    "                stack.append(op)\n",
    "                num =0\n",
    "                op = '+'\n",
    "            \n",
    "            elif i == len(s)-1 or s[i] in '+-*/)':\n",
    "                helper(op,num)\n",
    "\n",
    "                if s[i] == ')':\n",
    "                    num =0\n",
    "                    while isinstance(stack[-1],int):\n",
    "                        num += stack.pop()\n",
    "                    op = stack.pop()\n",
    "                    helper(op,num)\n",
    "                \n",
    "                num =0\n",
    "                op = s[i]\n",
    "\n",
    "        helper(op,num)\n",
    "        return sum(stack)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    stack_num = []\n",
    "    stack_opt = []\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "       \n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                self.stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                self.stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while self.stack_opt[-1]!='(':\n",
    "                    res = self.calc()\n",
    "                    self.stack_num.append(res)\n",
    "                self.stack_opt.pop()\n",
    "            else:\n",
    "                while self.stack_opt and priorty[self.stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    res = self.calc()\n",
    "                    self.stack_num.append(res)\n",
    "                self.stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while self.stack_opt:\n",
    "            res = self.calc()\n",
    "            self.stack_num.append(res)\n",
    "        return self.stack_num[-1]\n",
    "    \n",
    "    def calc(self):\n",
    "        opt = self.stack_opt.pop()\n",
    "        num1 = self.stack_num.pop()\n",
    "        num2 = self.stack_num.pop()\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2) / int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    op_priority = {'+': 0, '-': 0, '*': 1, '/': 1, '%': 1, '^': 2}\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = \"(\" + s.replace(\" \", \"\").replace(\"(-\", \"(0-\") + \")\"\n",
    "        # operators & numbers\n",
    "        op_stack, num_stack = [], []\n",
    "\n",
    "        i = 0\n",
    "        while i < len(s):\n",
    "            c = s[i]\n",
    "            i += 1\n",
    "            if c.isdigit():  # a number\n",
    "                num = int(c)\n",
    "                while i < len(s) and s[i].isdigit():\n",
    "                    num = num * 10 + int(s[i])\n",
    "                    i += 1\n",
    "                num_stack.append(num)\n",
    "            elif c == '(':  # (\n",
    "                op_stack.append(c)\n",
    "            elif c == ')':  # calculate until see '('\n",
    "                while op_stack and op_stack[-1] != '(':\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.pop()\n",
    "            else:\n",
    "                while op_stack and op_stack[-1] != '(' and self.op_priority[op_stack[-1]] >= self.op_priority[c]:\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.append(c)\n",
    "\n",
    "        return num_stack[0]\n",
    "\n",
    "    def calc(self, num_stack: list, op_stack: list) -> None:\n",
    "        op, y, x = op_stack.pop(), num_stack.pop(), num_stack.pop() if num_stack else 0\n",
    "        ans = 0\n",
    "        if op == '+':\n",
    "            ans = x + y\n",
    "        elif op == '-':\n",
    "            ans = x - y\n",
    "        elif op == '*':\n",
    "            ans = x * y\n",
    "        elif op == '/':\n",
    "            ans = x / y\n",
    "        elif op == '%':\n",
    "            ans = x % y\n",
    "        elif op == '^':\n",
    "            ans = pow(x, y)\n",
    "        num_stack.append(int(ans))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        def pair_cal(v1, v2, op):\n",
    "            if op == '+':\n",
    "                return int(v1) + int(v2)\n",
    "            elif op == '-':\n",
    "                return int(v1) - int(v2)\n",
    "            elif op == '*':\n",
    "                return int(v1) * int(v2)\n",
    "            elif op == '/':\n",
    "                # python里面//是向下取整，比如-3//4=-1，而不是0；需要靠近0取整(测试用例)\n",
    "                return int(int(v1) / int(v2))\n",
    "        \n",
    "        priority = {'*':2, '/':2, '+':1, '-':1, '(':0, ')':0}\n",
    "        stack_num, stack_op = [], []\n",
    "\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] == ' ': # 空格跳过\n",
    "                i += 1\n",
    "                continue\n",
    "\n",
    "            if i >= n:\n",
    "                break\n",
    "            \n",
    "            if '0' <= s[i] <= '9': # 将多位数字组成一个整数，入栈\n",
    "                num = \"\"\n",
    "                while i < n and '0' <= s[i] <= '9':\n",
    "                    num += s[i]\n",
    "                    i += 1\n",
    "                stack_num.append(int(num))\n",
    "            \n",
    "            if i >= n:\n",
    "                break\n",
    "\n",
    "            if s[i] == '(':\n",
    "                stack_op.append('(')\n",
    "\n",
    "            elif s[i] == ')':\n",
    "                while stack_op and stack_op[-1] != '(':\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.pop() # 弹出(\n",
    "            \n",
    "\n",
    "            else:\n",
    "                while stack_op and priority[stack_op[-1]] >= priority[s[i]]:\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.append(s[i])\n",
    "\n",
    "            i += 1\n",
    "\n",
    "        while stack_op: # 遍历完成后，栈里可能还剩一个计算符（优先级较低，没能在遍历的时候优先计算了）\n",
    "            op = stack_op.pop()\n",
    "            num1 = stack_num.pop()\n",
    "            num2 = stack_num.pop()\n",
    "            stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "        return stack_num[-1]\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # two stacks\n",
    "        stk_num = []\n",
    "        stk_op = []\n",
    "        i = 0\n",
    "        priority = {'(': 0, ')': 0, '+': 1, '-': 1, '*': 2, '/': 2}\n",
    "        while i < len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if s[i].isdigit():\n",
    "                num = int(s[i])\n",
    "                i += 1\n",
    "                while i < len(s) and s[i].isdigit():\n",
    "                    num = num * 10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                stk_num.append(int(num))\n",
    "                continue\n",
    "            if s[i] == '(':\n",
    "                stk_op.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while stk_op[-1] != '(':\n",
    "                    self.execCompute(stk_num, stk_op)\n",
    "                stk_op.pop()\n",
    "            else:\n",
    "                while stk_op and priority[stk_op[-1]] >= priority[s[i]]:\n",
    "                    self.execCompute(stk_num, stk_op)\n",
    "                stk_op.append(s[i])\n",
    "            i += 1\n",
    "        while stk_op:\n",
    "            self.execCompute(stk_num, stk_op)\n",
    "        return stk_num[-1]\n",
    "    \n",
    "    def execCompute(self, stk_num, stk_op):\n",
    "        op = stk_op.pop()\n",
    "        num2 = stk_num.pop()\n",
    "        num1 = stk_num.pop()\n",
    "        stk_num.append(self.op(num1, num2, op))\n",
    "        \n",
    "    def op(self, num1, num2, op):\n",
    "        if op == '+':\n",
    "            return num1 + num2\n",
    "        if op == '-':\n",
    "            return num1 - num2\n",
    "        if op == '*':\n",
    "            return num1 * num2\n",
    "        return int(num1 / num2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    op_map = {\n",
    "        \"(\": 0,\n",
    "        \")\": 0,\n",
    "        \"+\": 1, \n",
    "        \"-\": 1,\n",
    "        \"*\": 2,\n",
    "        \"/\": 2,\n",
    "        \"^\": 3\n",
    "    }\n",
    "    def calc(self, num_stack, op_stack):\n",
    "        if len(num_stack) < 2 or not op_stack:\n",
    "            return \n",
    "        b = num_stack.pop()\n",
    "        a = num_stack.pop()\n",
    "        op = op_stack.pop()\n",
    "        \n",
    "        res = 0\n",
    "        if op == '+':\n",
    "            res = a + b \n",
    "        elif op == '-':\n",
    "            res = a - b\n",
    "        elif op == '*':\n",
    "            res = a * b\n",
    "        elif op == '/':\n",
    "            res = int(a / b)\n",
    "        elif op == '^':\n",
    "            res = a ** b\n",
    "        num_stack.append(res)\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = s.replace(\" \", \"\").replace(\"(-\", \"(0-\").replace(\"(+\", \"(0+\")\n",
    "        num_stack = [0]\n",
    "        op_stack = []\n",
    "        i = 0 \n",
    "        while i < len(s):\n",
    "            if s[i].isdigit():\n",
    "                j = i\n",
    "                while i+1 < len(s) and s[i+1].isdigit():\n",
    "                    i += 1\n",
    "                num_stack.append(int(s[j:i+1]))\n",
    "            elif s[i] == '(':\n",
    "                op_stack.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while op_stack[-1] != '(':\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.pop()  # 弹出左括号\n",
    "            else:\n",
    "                while op_stack and self.op_map[op_stack[-1]] >= self.op_map[s[i]]:\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.append(s[i])          \n",
    "            i += 1\n",
    "        while op_stack:\n",
    "            self.calc(num_stack, op_stack)\n",
    "        \n",
    "        return num_stack[-1]\n",
    "\n",
    "# class Solution:\n",
    "#     def calc(self, num1, num2, operator):\n",
    "#         if operator == \"+\":\n",
    "#             return int(num2) + int(num1)\n",
    "#         elif operator == \"-\":\n",
    "#             return int(num2) - int(num1)\n",
    "#         elif operator == \"*\":\n",
    "#             return int(num2) * int(num1)\n",
    "#         elif operator == \"/\":\n",
    "#             return int(int(num2) / int(num1))\n",
    "\n",
    "#     def calculate(self, s: str) -> int:\n",
    "#         stack_num = []\n",
    "#         stack_opt = []\n",
    "#         i = 0\n",
    "#         priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "#         while i < len(s):\n",
    "#             if s[i]==\" \": \n",
    "#                 i += 1 \n",
    "#                 continue\n",
    "#             if '0'<=s[i]<='9':\n",
    "#                 j = i\n",
    "#                 while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "#                     i += 1\n",
    "#                 num = int(s[j:i+1])\n",
    "#                 stack_num.append(num)\n",
    "#             elif s[i] == \"(\":\n",
    "#                 stack_opt.append(s[i])\n",
    "#             elif s[i] == \")\":\n",
    "#                 while stack_opt[-1] != \"(\":\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.pop() # pop \"(\"\n",
    "#             else:\n",
    "#                 while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.append(s[i])\n",
    "#             i += 1\n",
    "#         while stack_opt:\n",
    "#             opt = stack_opt.pop()\n",
    "#             A = stack_num.pop()\n",
    "#             B = stack_num.pop()\n",
    "#             res = self.calc(A, B, opt)\n",
    "#             stack_num.append(res)\n",
    "#         return stack_num[-1]\n",
    "\n",
    "\n",
    "        # stack_num = []\n",
    "        # stack_opt = []\n",
    "        # i = 0\n",
    "        # priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        # while i<len(s):\n",
    "        #     if s[i]==' ':\n",
    "        #         i += 1\n",
    "        #         continue\n",
    "        #     if '0'<=s[i]<='9':\n",
    "        #         j = i\n",
    "        #         while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "        #             i += 1\n",
    "        #         num = int(s[j:i+1])\n",
    "        #         stack_num.append(num)\n",
    "        #     elif s[i]=='(':\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     elif s[i]==')':\n",
    "        #         while stack_opt[-1]!='(':\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.pop()\n",
    "        #     else:\n",
    "        #         while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     i += 1\n",
    "\n",
    "        # while stack_opt:\n",
    "        #     opt = stack_opt.pop()\n",
    "        #     A = stack_num.pop()\n",
    "        #     B = stack_num.pop()\n",
    "        #     res = self.calc(A,B,opt)\n",
    "        #     stack_num.append(res)\n",
    "        # return stack_num[-1]\n",
    "    \n",
    "    # def calc(self,num1,num2,opt):\n",
    "    #     if opt=='+':\n",
    "    #         return int(num1)+int(num2)\n",
    "    #     elif opt=='-':\n",
    "    #         return int(num2)-int(num1)\n",
    "    #     elif opt=='*':\n",
    "    #         return int(num2)*int(num1)\n",
    "    #     elif opt=='/':\n",
    "    #         return int(int(num2)/int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        #栈应用的炒鸡模拟题\n",
    "        check={\"+\":0,\"-\":0,\"*\":1,\"/\":1,\"(\":2,\")\":0,\"#\":-1}\n",
    "        #比较运算符号的优先级\n",
    "        def op(a,b,x):\n",
    "            if x==\"+\":\n",
    "                return a+b\n",
    "            elif x==\"-\":\n",
    "                return a-b\n",
    "            elif x==\"*\":\n",
    "                return a*b\n",
    "            else:\n",
    "                return int(a/b)\n",
    "        num_stack=[]\n",
    "        op_stack=[]\n",
    "        pre=None\n",
    "        s=s+\"#\"\n",
    "        for ch in s:\n",
    "            #数字直接处理\n",
    "            if ch.isdigit():\n",
    "                if pre is None: pre=0\n",
    "                pre=pre*10+int(ch)\n",
    "            else:\n",
    "                if pre is not None:\n",
    "                    num_stack.append(pre)\n",
    "                while op_stack and check[op_stack[-1]]>=check[ch] and op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                if ch==\")\":\n",
    "                    while op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                    op_stack.pop()\n",
    "                else:\n",
    "                    op_stack.append(ch)\n",
    "                #运算符号\n",
    "                pre=None\n",
    "        return num_stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2, \"^\":3}\n",
    "    def calc(self, num_stack, op_stack):\n",
    "        if len(num_stack) < 2 or not op_stack:\n",
    "            return \n",
    "        b = num_stack.pop()\n",
    "        a = num_stack.pop()\n",
    "        op = op_stack.pop()\n",
    "        res = None\n",
    "        if op == \"+\":\n",
    "            res = a + b \n",
    "        elif op == \"-\":\n",
    "            res = a - b\n",
    "        elif op == \"*\":\n",
    "            res = a * b \n",
    "        elif op == \"/\":\n",
    "            res = int(a / b)\n",
    "        elif op == \"^\":\n",
    "            res = a**b \n",
    "        num_stack.append(res)\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = s.replace(\" \", \"\").replace(\"(-\", \"(0-\").replace(\"(+\", \"(0+\")\n",
    "        n = len(s)\n",
    "        num_stack = [0]\n",
    "        op_stack = []\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i].isdigit():\n",
    "                j = i \n",
    "                while i+1 < len(s) and s[i+1].isdigit():\n",
    "                    i += 1\n",
    "                num_stack.append(int(s[j:i+1]))\n",
    "            elif s[i] == \"(\":\n",
    "                op_stack.append(s[i])\n",
    "            elif s[i] == \")\":\n",
    "                while op_stack and op_stack[-1] != \"(\":\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.pop()\n",
    "            else:\n",
    "                while op_stack and self.priority[op_stack[-1]] >= self.priority[s[i]]:\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.append(s[i])\n",
    "            i += 1\n",
    "        while op_stack:\n",
    "            self.calc(num_stack, op_stack)\n",
    "        return num_stack[-1]\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# class Solution:\n",
    "#     op_map = {\n",
    "#         \"(\": 0,\n",
    "#         \")\": 0,\n",
    "#         \"+\": 1, \n",
    "#         \"-\": 1,\n",
    "#         \"*\": 2,\n",
    "#         \"/\": 2,\n",
    "#         \"^\": 3\n",
    "#     }\n",
    "#     def calc(self, num_stack, op_stack):\n",
    "#         if len(num_stack) < 2 or not op_stack:\n",
    "#             return \n",
    "#         b = num_stack.pop()\n",
    "#         a = num_stack.pop()\n",
    "#         op = op_stack.pop()\n",
    "        \n",
    "#         res = 0\n",
    "#         if op == '+':\n",
    "#             res = a + b \n",
    "#         elif op == '-':\n",
    "#             res = a - b\n",
    "#         elif op == '*':\n",
    "#             res = a * b\n",
    "#         elif op == '/':\n",
    "#             res = int(a / b)\n",
    "#         elif op == '^':\n",
    "#             res = a ** b\n",
    "#         num_stack.append(res)\n",
    "\n",
    "#     def calculate(self, s: str) -> int:\n",
    "#         s = s.replace(\" \", \"\").replace(\"(-\", \"(0-\").replace(\"(+\", \"(0+\")\n",
    "#         num_stack = [0]\n",
    "#         op_stack = []\n",
    "#         i = 0 \n",
    "#         while i < len(s):\n",
    "#             if s[i].isdigit():\n",
    "#                 j = i\n",
    "#                 while i+1 < len(s) and s[i+1].isdigit():\n",
    "#                     i += 1\n",
    "#                 num_stack.append(int(s[j:i+1]))\n",
    "#             elif s[i] == '(':\n",
    "#                 op_stack.append(s[i])\n",
    "#             elif s[i] == ')':\n",
    "#                 while op_stack[-1] != '(':\n",
    "#                     self.calc(num_stack, op_stack)\n",
    "#                 op_stack.pop()  # 弹出左括号\n",
    "#             else:\n",
    "#                 while op_stack and self.op_map[op_stack[-1]] >= self.op_map[s[i]]:\n",
    "#                     self.calc(num_stack, op_stack)\n",
    "#                 op_stack.append(s[i])          \n",
    "#             i += 1\n",
    "#         while op_stack:\n",
    "#             self.calc(num_stack, op_stack)\n",
    "        \n",
    "#         return num_stack[-1]\n",
    "\n",
    "# class Solution:\n",
    "#     def calc(self, num1, num2, operator):\n",
    "#         if operator == \"+\":\n",
    "#             return int(num2) + int(num1)\n",
    "#         elif operator == \"-\":\n",
    "#             return int(num2) - int(num1)\n",
    "#         elif operator == \"*\":\n",
    "#             return int(num2) * int(num1)\n",
    "#         elif operator == \"/\":\n",
    "#             return int(int(num2) / int(num1))\n",
    "\n",
    "#     def calculate(self, s: str) -> int:\n",
    "#         stack_num = []\n",
    "#         stack_opt = []\n",
    "#         i = 0\n",
    "#         priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "#         while i < len(s):\n",
    "#             if s[i]==\" \": \n",
    "#                 i += 1 \n",
    "#                 continue\n",
    "#             if '0'<=s[i]<='9':\n",
    "#                 j = i\n",
    "#                 while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "#                     i += 1\n",
    "#                 num = int(s[j:i+1])\n",
    "#                 stack_num.append(num)\n",
    "#             elif s[i] == \"(\":\n",
    "#                 stack_opt.append(s[i])\n",
    "#             elif s[i] == \")\":\n",
    "#                 while stack_opt[-1] != \"(\":\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.pop() # pop \"(\"\n",
    "#             else:\n",
    "#                 while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.append(s[i])\n",
    "#             i += 1\n",
    "#         while stack_opt:\n",
    "#             opt = stack_opt.pop()\n",
    "#             A = stack_num.pop()\n",
    "#             B = stack_num.pop()\n",
    "#             res = self.calc(A, B, opt)\n",
    "#             stack_num.append(res)\n",
    "#         return stack_num[-1]\n",
    "\n",
    "\n",
    "        # stack_num = []\n",
    "        # stack_opt = []\n",
    "        # i = 0\n",
    "        # priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        # while i<len(s):\n",
    "        #     if s[i]==' ':\n",
    "        #         i += 1\n",
    "        #         continue\n",
    "        #     if '0'<=s[i]<='9':\n",
    "        #         j = i\n",
    "        #         while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "        #             i += 1\n",
    "        #         num = int(s[j:i+1])\n",
    "        #         stack_num.append(num)\n",
    "        #     elif s[i]=='(':\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     elif s[i]==')':\n",
    "        #         while stack_opt[-1]!='(':\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.pop()\n",
    "        #     else:\n",
    "        #         while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     i += 1\n",
    "\n",
    "        # while stack_opt:\n",
    "        #     opt = stack_opt.pop()\n",
    "        #     A = stack_num.pop()\n",
    "        #     B = stack_num.pop()\n",
    "        #     res = self.calc(A,B,opt)\n",
    "        #     stack_num.append(res)\n",
    "        # return stack_num[-1]\n",
    "    \n",
    "    # def calc(self,num1,num2,opt):\n",
    "    #     if opt=='+':\n",
    "    #         return int(num1)+int(num2)\n",
    "    #     elif opt=='-':\n",
    "    #         return int(num2)-int(num1)\n",
    "    #     elif opt=='*':\n",
    "    #         return int(num2)*int(num1)\n",
    "    #     elif opt=='/':\n",
    "    #         return int(int(num2)/int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s + '+')\n",
    "\n",
    "        def _calc():\n",
    "            stack = []\n",
    "            num = 0\n",
    "            preop = '+'\n",
    "\n",
    "            while s:\n",
    "                c = s.popleft()\n",
    "\n",
    "                if c.isdigit():\n",
    "                    num = num * 10 + int(c)\n",
    "                elif c == '(':\n",
    "                    num = _calc()\n",
    "                elif c in \"+-*/)\":\n",
    "                    if preop == '+':\n",
    "                        stack.append(num)\n",
    "                    elif preop == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif preop == '*':\n",
    "                        stack[-1] *= num\n",
    "                    elif preop == '/':\n",
    "                        stack[-1] = int(stack[-1] / num)\n",
    "\n",
    "                    if c == ')': break\n",
    "\n",
    "                    num = 0\n",
    "                    preop = c\n",
    "                \n",
    "            return sum(stack)\n",
    "        \n",
    "        return _calc()\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        num_stack = []\n",
    "        op_stack = []\n",
    "        cur = None\n",
    "        s = s + '+'\n",
    "        for i in s:\n",
    "            if i in '0123456789':\n",
    "                if cur is None:\n",
    "                    cur = ord(i) - ord('0')\n",
    "                else:\n",
    "                    cur = cur*10 + ord(i) - ord('0')\n",
    "            else:\n",
    "                if i == '(':\n",
    "                    op_stack.append(i)\n",
    "                    if cur is not None:\n",
    "                        num_stack.append(cur)\n",
    "                        cur = None\n",
    "                elif i in '+-*/':\n",
    "                    if op_stack:\n",
    "                        o = op_stack[-1]\n",
    "                        if o in '+-(':\n",
    "                            num_stack.append(cur)\n",
    "                        elif o in '*/':\n",
    "                            a = num_stack.pop()\n",
    "                            o = op_stack.pop()\n",
    "                            num_stack.append(self.domath(a, cur, o))\n",
    "                    else:\n",
    "                        num_stack.append(cur)\n",
    "                    op_stack.append(i)\n",
    "                    cur = None\n",
    "                elif i == ')':\n",
    "                    if op_stack[-1] in '*/':\n",
    "                        a = num_stack.pop()\n",
    "                        o = op_stack.pop()\n",
    "                        num_stack.append(self.domath(a, cur, o))\n",
    "                    elif cur is not None:\n",
    "                        num_stack.append(cur)\n",
    "                        cur = None\n",
    "                    s1 = []\n",
    "                    s2 = []\n",
    "                    while op_stack[-1] != '(':\n",
    "                        s1.append(op_stack.pop())\n",
    "                        s2.append(num_stack.pop())\n",
    "                    op_stack.pop()\n",
    "                    a = num_stack.pop()\n",
    "                    while s2:\n",
    "                        o = s1.pop()\n",
    "                        b = s2.pop()\n",
    "                        a = self.domath(a, b, o)\n",
    "                    cur = a\n",
    "        if cur is not None:\n",
    "            num_stack.append(cur)\n",
    "            cur = None\n",
    "        if len(num_stack) >= 1:\n",
    "            ans = num_stack.pop(0)\n",
    "        while num_stack:\n",
    "            o = op_stack.pop(0)\n",
    "            b = num_stack.pop(0)\n",
    "            ans = self.domath(ans, b, o)\n",
    "        return ans\n",
    "\n",
    "    def domath(self, a, b, o):\n",
    "        if o == '+':\n",
    "            return a+b\n",
    "        elif o == '-':\n",
    "            return a-b\n",
    "        elif o == '*':\n",
    "            return a*b\n",
    "        elif o == '/':\n",
    "            if a/b < 0:\n",
    "                return (a//b)+1\n",
    "            else:\n",
    "                return a//b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        nums, oprs = [], []\n",
    "        i, n = 0, len(s)\n",
    "        priority = { '+': 1, '-': 1, '*': 2, '/': 2 }\n",
    "\n",
    "        def calc():\n",
    "            num2, num1 = nums.pop(), nums.pop()\n",
    "            opr = oprs.pop()\n",
    "            if opr == '+':\n",
    "                ans = num1 + num2\n",
    "            elif opr == '-':\n",
    "                ans = num1 - num2\n",
    "            elif opr == '*':\n",
    "                ans = num1 * num2\n",
    "            elif opr == '/':\n",
    "                ans = int(num1 / num2)\n",
    "            nums.append(ans)\n",
    "\n",
    "        while i < n:\n",
    "            c = s[i]\n",
    "            if c.isdigit():\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = 10 * num + int(s[i])\n",
    "                    i += 1\n",
    "                nums.append(num)\n",
    "                continue\n",
    "            elif c == '(':\n",
    "                oprs.append(c)\n",
    "            elif c in '+-*/':\n",
    "                while oprs and oprs[-1] != '(' and priority[c] <= priority[oprs[-1]]:\n",
    "                    calc()\n",
    "                oprs.append(c)\n",
    "            elif c == ')':\n",
    "                while oprs[-1] != '(':\n",
    "                    calc()\n",
    "                oprs.pop()\n",
    "            i += 1\n",
    "        while oprs:\n",
    "            calc()\n",
    "        return nums[0]\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        def pair_cal(v1, v2, op):\n",
    "            if op == '+':\n",
    "                return int(v1) + int(v2)\n",
    "            elif op == '-':\n",
    "                return int(v1) - int(v2)\n",
    "            elif op == '*':\n",
    "                return int(v1) * int(v2)\n",
    "            elif op == '/':\n",
    "                # python里面//是向下取整，比如-3//4=-1，而不是0；需要靠近0取整(测试用例)\n",
    "                return int(int(v1) / int(v2))\n",
    "        \n",
    "        priority = {'*':2, '/':2, '+':1, '-':1, '(':0, ')':0}\n",
    "        stack_num, stack_op = [], []\n",
    "\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] == ' ': # 空格跳过\n",
    "                i += 1\n",
    "                continue\n",
    "\n",
    "            if i >= n:\n",
    "                break\n",
    "            \n",
    "            if '0' <= s[i] <= '9': # 将多位数字组成一个整数，入栈\n",
    "                num = \"\"\n",
    "                while i < n and '0' <= s[i] <= '9':\n",
    "                    num += s[i]\n",
    "                    i += 1\n",
    "                stack_num.append(int(num))\n",
    "            \n",
    "            if i >= n:\n",
    "                break\n",
    "\n",
    "            if s[i] == '(':\n",
    "                stack_op.append('(')\n",
    "\n",
    "            elif s[i] == ')':\n",
    "                while stack_op and stack_op[-1] != '(':\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.pop() # 弹出(\n",
    "            \n",
    "\n",
    "            else:\n",
    "                while stack_op and priority[stack_op[-1]] >= priority[s[i]]:\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.append(s[i])\n",
    "\n",
    "            i += 1\n",
    "\n",
    "        while stack_op: # 遍历完成后，栈里可能还剩一个计算符（优先级较低，没能在遍历的时候优先计算了）\n",
    "            op = stack_op.pop()\n",
    "            num1 = stack_num.pop()\n",
    "            num2 = stack_num.pop()\n",
    "            stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "        return stack_num[-1]\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        check={\"+\":0,\"-\":0,\"*\":1,\"/\":1,\"(\":2,\")\":0,\"#\":-1}\n",
    "        #比较运算符号的优先级\n",
    "        def op(a,b,x):\n",
    "            if x==\"+\":\n",
    "                return a+b\n",
    "            elif x==\"-\":\n",
    "                return a-b\n",
    "            elif x==\"*\":\n",
    "                return a*b\n",
    "            else:\n",
    "                return int(a/b)\n",
    "        num_stack=[]\n",
    "        op_stack=[]\n",
    "        pre=None\n",
    "        s=s+\"#\"\n",
    "        for ch in s:\n",
    "            #数字直接处理\n",
    "            if ch.isdigit():\n",
    "                if pre is None: pre=0\n",
    "                pre=pre*10+int(ch)\n",
    "            else:\n",
    "                if pre is not None:\n",
    "                    num_stack.append(pre)\n",
    "                while op_stack and check[op_stack[-1]]>=check[ch] and op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                if ch==\")\":\n",
    "                    while op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                    op_stack.pop()\n",
    "                else:\n",
    "                    op_stack.append(ch)\n",
    "                #运算符号\n",
    "                pre=None\n",
    "        return num_stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def cal():\n",
    "            n1 = num_stack.pop()\n",
    "            n2 = num_stack.pop()\n",
    "            op = op_stack.pop()\n",
    "            if op=='+':\n",
    "                num_stack.append(n2+n1)\n",
    "            elif op=='-':\n",
    "                num_stack.append(n2-n1)\n",
    "            elif op=='*':\n",
    "                num_stack.append(n2*n1)\n",
    "            elif op=='/':\n",
    "                num_stack.append(int(n2/n1))\n",
    "\n",
    "        idx = 0\n",
    "        num_stack = []\n",
    "        op_stack = []\n",
    "    \n",
    "        n = len(s)\n",
    "        while idx<=n-1:\n",
    "            c = s[idx]\n",
    "            if c==')':\n",
    "                while op_stack and op_stack[-1]!='(':\n",
    "                    cal()\n",
    "                op_stack.pop()\n",
    "                idx+=1\n",
    "            elif c=='(':\n",
    "                op_stack.append(c)\n",
    "                idx+=1\n",
    "            elif c in ['+', '-']:\n",
    "                while op_stack and op_stack[-1] in ['*', '/', '+', '-']:\n",
    "                    cal()\n",
    "                op_stack.append(c)\n",
    "                idx+=1\n",
    "            elif c in ['*', '/']:\n",
    "                while op_stack and op_stack[-1] in ['*', '/']:\n",
    "                    cal()\n",
    "                op_stack.append(c)\n",
    "                idx+=1\n",
    "            else:\n",
    "                num = 0\n",
    "                while idx<=n-1 and '0'<=s[idx]<='9':\n",
    "                    num = num*10+int(s[idx])\n",
    "                    idx+=1\n",
    "                num_stack.append(num)\n",
    "\n",
    "        while op_stack:\n",
    "            cal()\n",
    "\n",
    "        return num_stack[0]\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def get_next_num(start_idx):\n",
    "            ans = ''\n",
    "\n",
    "            for ii in range(start_idx, len(s)):\n",
    "                if not s[ii].isnumeric():\n",
    "                    break\n",
    "                \n",
    "                ans += s[ii]\n",
    "\n",
    "            return int(ans), ii\n",
    "        \n",
    "        def cal_stack(num_stack, sign_stack):\n",
    "            ans = 0\n",
    "            while sign_stack:\n",
    "                num = num_stack.pop()\n",
    "                ans = ans + num if sign_stack.pop() == '+' else ans - num\n",
    "            \n",
    "            return ans + num_stack[0]            \n",
    "\n",
    "        def cal_parenthesis(start_idx):\n",
    "            ii = start_idx\n",
    "            num_stack = []\n",
    "            sign_stack = []\n",
    "            plus_minus = {'+', '-'}\n",
    "            times_divides = {'*', '/'}\n",
    "            while ii < len(s):\n",
    "                if s[ii] == ')':\n",
    "                    break\n",
    "                \n",
    "                if s[ii] in times_divides or s[ii] in plus_minus:\n",
    "                    sign_stack.append(s[ii])\n",
    "                    ii += 1\n",
    "\n",
    "                if s[ii] == '(':\n",
    "                    num, ii = cal_parenthesis(ii + 1)\n",
    "                    num_stack.append(num)\n",
    "                    ii += 1\n",
    "                elif s[ii].isnumeric():\n",
    "                    num, ii = get_next_num(ii)\n",
    "                    num_stack.append(num)\n",
    "                while sign_stack and (sign_stack[-1] in times_divides):\n",
    "                    sign = sign_stack.pop()\n",
    "                    num = num_stack.pop()\n",
    "                    prev_num = num_stack.pop()\n",
    "                    num = prev_num * num if sign == '*' else int(prev_num / num)\n",
    "                    num_stack.append(num)\n",
    "\n",
    "            # print(num_stack, sign_stack)\n",
    "            return cal_stack(num_stack, sign_stack), ii\n",
    "        \n",
    "        s = f'{s})'\n",
    "        return cal_parenthesis(0)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s):\n",
    "            # print(s)\n",
    "            stack = []\n",
    "            num = 0\n",
    "            sign = '+'\n",
    "            while s:\n",
    "                c = s.popleft()\n",
    "                if c == \"(\":\n",
    "                    num = helper(s)  \n",
    "                if c.isdigit():\n",
    "                    num = num*10+int(c)  \n",
    "                if c in '+-*/)' or len(s) == 0:\n",
    "                    # print(sign,num,c)\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    if sign =='-':\n",
    "                        stack.append(-num)\n",
    "                    if sign =='*':\n",
    "                        stack.append(stack.pop()*num)\n",
    "                    if sign == '/':\n",
    "                        stack.append(int(stack.pop()/num))\n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                if c == \")\":\n",
    "                    break\n",
    "                # print(stack)\n",
    "            return sum(stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = \"(\" + s + \")\"\n",
    "        pm = {\n",
    "            \"*\" : 2,\n",
    "            \"/\" : 2,\n",
    "            \"+\" : 1,\n",
    "            \"-\" : 1,\n",
    "            \"(\" : 0,\n",
    "            \")\" : 0\n",
    "        }\n",
    "        nums, ops, i, n = [], [], 0, len(s)\n",
    "\n",
    "        def cal(a, b, op):\n",
    "            if op == \"+\":\n",
    "                return a + b\n",
    "            elif op == \"-\":\n",
    "                return a - b\n",
    "            elif op == \"*\":\n",
    "                return a * b\n",
    "            else:\n",
    "                return int(a / b)\n",
    "        \n",
    "        def eval():\n",
    "            b = nums.pop()\n",
    "            a = nums.pop()\n",
    "            op = ops.pop()\n",
    "            nums.append(cal(a, b, op))\n",
    "        \n",
    "        def num(i):\n",
    "            cur = \"\"\n",
    "            while i < n and s[i].isdigit():\n",
    "                cur += s[i]\n",
    "                i += 1\n",
    "            nums.append(int(cur))\n",
    "            return i\n",
    "        \n",
    "        def left(i):\n",
    "            ops.append(\"(\")\n",
    "            # 检查左括号后的字符\n",
    "            i += 1\n",
    "            while i< n and s[i] == \" \":\n",
    "                i += 1\n",
    "            if i < n and s[i] == '-':\n",
    "                nums.append(0)  # 将 0 压入栈中，以处理负数\n",
    "            return i\n",
    "        \n",
    "        def right(i):\n",
    "            while ops[-1] != \"(\":\n",
    "                eval()\n",
    "            ops.pop()\n",
    "            return i + 1\n",
    "        \n",
    "        def opf(i):\n",
    "            while ops and pm[ops[-1]] >= pm[s[i]]:\n",
    "                eval()\n",
    "            ops.append(s[i])\n",
    "            return i + 1\n",
    "        \n",
    "        def empty(i):\n",
    "            return i + 1\n",
    "        \n",
    "        opm = {\n",
    "            \"+\": opf,\n",
    "            \"-\": opf,\n",
    "            \"*\": opf,\n",
    "            \"/\": opf,\n",
    "            \"(\": left,\n",
    "            \")\": right,\n",
    "            \" \": empty\n",
    "        }\n",
    "        for j in \"0123456789\":\n",
    "            opm[j] = num\n",
    "        \n",
    "        while i < n:\n",
    "            i = opm[s[i]](i)\n",
    "        \n",
    "        while ops:\n",
    "            eval()\n",
    "        \n",
    "        return nums.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[0]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2)/int(num1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        num_stack = [] \n",
    "        opt_stack = []\n",
    "        i = 0\n",
    "        priority = {'*':2,'/':2,'+':1,'-':1,'(':0,')':0}\n",
    "        while i < len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0' <= s[i] <= '9':\n",
    "                num = 0\n",
    "                while i < len(s) and '0' <= s[i] <= '9':\n",
    "                    num = num * 10 + int(s[i])\n",
    "                    i += 1\n",
    "                i -= 1\n",
    "                num_stack.append(num)\n",
    "            elif s[i] == '(':\n",
    "                opt_stack.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while opt_stack and opt_stack[-1] != '(':\n",
    "                    opt = opt_stack.pop()\n",
    "                    num2 = num_stack.pop()\n",
    "                    num1 = num_stack.pop()\n",
    "                    num_stack.append(self.cal(num1,num2,opt))\n",
    "                opt_stack.pop()\n",
    "            else:\n",
    "                while opt_stack and priority[opt_stack[-1]]>=priority[s[i]]:\n",
    "                    opt = opt_stack.pop()\n",
    "                    A = num_stack.pop()\n",
    "                    B = num_stack.pop()\n",
    "                    res = self.cal(B,A,opt)\n",
    "                    num_stack.append(res)\n",
    "                opt_stack.append(s[i])\n",
    "            i += 1\n",
    "        while opt_stack:\n",
    "    \n",
    "            opt = opt_stack.pop()\n",
    "            A = num_stack.pop()\n",
    "            B = num_stack.pop()\n",
    "            res = self.cal(B,A,opt)\n",
    "            num_stack.append(res)\n",
    "        return num_stack[-1]\n",
    "        \n",
    "    def cal(self,num1,num2,opt):\n",
    "        if opt == '+':\n",
    "            return num1 + num2\n",
    "        elif opt == '-':\n",
    "            return num1 - num2\n",
    "        elif opt == '*':\n",
    "            return num1 * num2\n",
    "        else:\n",
    "            return int(num1/num2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "     def calculate(self, s: str) -> int:\n",
    "        def addNum(x, stack, lastSign):\n",
    "            if lastSign == '*':\n",
    "                stack.append(stack.pop() * x)\n",
    "            elif lastSign == '/':\n",
    "                stack.append(int(stack.pop() / x))\n",
    "            elif lastSign == '-':\n",
    "                stack.append(-x)\n",
    "            else:\n",
    "                stack.append(x)\n",
    "\n",
    "        def helper(index):\n",
    "            stack = []\n",
    "            lastSign = ''\n",
    "            cur = ''\n",
    "            while index < len(s):\n",
    "                c = s[index]\n",
    "                if c in '0123456789':\n",
    "                    cur += c\n",
    "                    index += 1\n",
    "                elif c in '+-':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        addNum(x, stack, lastSign)\n",
    "                    lastSign = c\n",
    "                    index += 1\n",
    "                    cur = ''\n",
    "                elif c in '*/':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        addNum(x, stack, lastSign)\n",
    "                    lastSign = c\n",
    "                    index += 1\n",
    "                    cur = ''\n",
    "                elif c == '(':\n",
    "                    x, index = helper(index + 1)\n",
    "                    addNum(x, stack, lastSign)\n",
    "                    lastSign = ''\n",
    "                elif c == ')':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        addNum(x, stack, lastSign)\n",
    "                    return sum(stack), index + 1\n",
    "\n",
    "            if cur != '':\n",
    "                x = int(cur)\n",
    "                addNum(x, stack, lastSign)\n",
    "            return sum(stack), index + 1\n",
    "\n",
    "        x, _ = helper(0)\n",
    "        return x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from enum import Enum, auto\n",
    "\n",
    "class CharType(Enum):\n",
    "    NUM = auto()\n",
    "    OP = auto()\n",
    "    LEFT_PAREN = auto()\n",
    "    RIGHT_PAREN = auto()\n",
    "    SPACE = auto()\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        pm = {\n",
    "            \"*\" : 2,\n",
    "            \"/\" : 2,\n",
    "            \"+\" : 1,\n",
    "            \"-\" : 1,\n",
    "            \"(\" : 0,\n",
    "            \")\" : 0\n",
    "        }\n",
    "        nums, ops, i, n = [], [], 0, len(s)\n",
    "\n",
    "        def cal(a, b, op):\n",
    "            if op == \"+\":\n",
    "                return a + b\n",
    "            elif op == \"-\":\n",
    "                return a - b\n",
    "            elif op == \"*\":\n",
    "                return a * b\n",
    "            else:\n",
    "                return int(a / b)\n",
    "        \n",
    "        def eval_expr():\n",
    "            nonlocal nums, ops\n",
    "            a = nums.pop()\n",
    "            b = nums.pop()\n",
    "            op = ops.pop()\n",
    "            nums.append(cal(b, a, op))\n",
    "        \n",
    "        def process_num():\n",
    "            nonlocal i\n",
    "            cur = \"\"\n",
    "            while i < n and s[i].isdigit():\n",
    "                cur += s[i]\n",
    "                i += 1\n",
    "            nums.append(int(cur))\n",
    "        \n",
    "        def process_left_paren():\n",
    "            nonlocal i\n",
    "            ops.append(\"(\")\n",
    "            i += 1\n",
    "        \n",
    "        def process_right_paren():\n",
    "            nonlocal i\n",
    "            while ops[-1] != \"(\":\n",
    "                eval_expr()\n",
    "            ops.pop()\n",
    "            i += 1\n",
    "        \n",
    "        def process_op():\n",
    "            nonlocal i\n",
    "            while ops and pm[ops[-1]] >= pm[s[i]]:\n",
    "                eval_expr()\n",
    "            ops.append(s[i])\n",
    "            i += 1\n",
    "        \n",
    "        def process_space():\n",
    "            nonlocal i\n",
    "            i += 1\n",
    "        \n",
    "        def get_char_type(char):\n",
    "            if char.isdigit():\n",
    "                return CharType.NUM\n",
    "            elif char in \"+-*/\":\n",
    "                return CharType.OP\n",
    "            elif char == \"(\":\n",
    "                return CharType.LEFT_PAREN\n",
    "            elif char == \")\":\n",
    "                return CharType.RIGHT_PAREN\n",
    "            elif char == \" \":\n",
    "                return CharType.SPACE\n",
    "        \n",
    "        while i < n:\n",
    "            char_type = get_char_type(s[i])\n",
    "            if char_type == CharType.NUM:\n",
    "                process_num()\n",
    "            elif char_type == CharType.OP:\n",
    "                process_op()\n",
    "            elif char_type == CharType.LEFT_PAREN:\n",
    "                process_left_paren()\n",
    "            elif char_type == CharType.RIGHT_PAREN:\n",
    "                process_right_paren()\n",
    "            elif char_type == CharType.SPACE:\n",
    "                process_space()\n",
    "        \n",
    "        while ops:\n",
    "            eval_expr()\n",
    "        \n",
    "        return nums.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        def cal(op, num):\n",
    "            if op=='+':\n",
    "                stack.append(num)\n",
    "            elif op=='-':\n",
    "                stack.append(-num)\n",
    "            elif op=='*':\n",
    "                stack.append(stack.pop()*num)\n",
    "            elif op=='/':\n",
    "                stack.append(int(stack.pop()/num))\n",
    "                \n",
    "        num, op = 0, '+'\n",
    "        for i in range(len(s)):\n",
    "            ch = s[i]\n",
    "            if ch.isdigit():\n",
    "                num = 10*num+int(ch)\n",
    "            elif ch!='(':\n",
    "                cal(op, num)\n",
    "                if ch==')':\n",
    "                    num = 0\n",
    "                    while type(stack[-1])==int:\n",
    "                        num += stack.pop()\n",
    "                    op = stack.pop()\n",
    "                    cal(op, num)\n",
    "                num, op = 0, ch\n",
    "            elif ch=='(':\n",
    "                stack.append(op)\n",
    "                num, op = 0, '+'\n",
    "        cal(op, num)\n",
    "        \n",
    "        return sum(stack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "            \n",
    "        def helper(s: List) -> int:\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "\n",
    "            while len(s) > 0:\n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = 10 * num + int(c)\n",
    "                # 遇到左括号开始递归计算 num\n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif sign == '/':\n",
    "                        # python 除法向 0 取整的写法\n",
    "                        stack[-1] = int(stack[-1] / float(num))       \n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                # 遇到右括号返回递归结果\n",
    "                if c == ')': break\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(collections.deque(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s)\n",
    "            \n",
    "        def _calculate() -> int:\n",
    "            stack = []\n",
    "            prev_operator = '+'\n",
    "            num = 0\n",
    "\n",
    "            while s:\n",
    "                char = s.popleft()\n",
    "                if char == '(':\n",
    "                    num = _calculate()\n",
    "\n",
    "                elif char.isdigit():\n",
    "                    num = 10 * num + int(char)\n",
    "\n",
    "                if char in \"+-*/)\" or not s:\n",
    "                    if prev_operator == '+':\n",
    "                        stack.append(num)\n",
    "                    elif prev_operator == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif prev_operator == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif prev_operator == '/':\n",
    "                        stack[-1] = int(stack[-1] / float(num))   \n",
    "                    if char == ')': break\n",
    "    \n",
    "                    num = 0\n",
    "                    prev_operator = char\n",
    "                # 遇到右括号返回递归结果\n",
    "            return sum(stack)\n",
    "\n",
    "        return _calculate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        return self.evalRPN(self.toRPN(s))\n",
    "\n",
    "    def toRPN(self, s):\n",
    "        s += '#' # endding\n",
    "        priority_table = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "        stk_op = ['$']\n",
    "        rpn = []\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] in priority_table:\n",
    "                # 若当前运算符为左括号或比stk_op栈顶运算符优先级更高的运算符，直接放入stk_op栈顶\n",
    "                if s[i] == '(' or priority_table[s[i]] > priority_table[stk_op[-1]] > 0:\n",
    "                    stk_op.append(s[i])\n",
    "                \n",
    "                # 否则弹出弹出stk_op栈顶运算符直到当前运算符优先级大于栈顶运算符优先级\n",
    "                # 如果当前运算符为结束符'#'，stk_op中则直到'$'前的所有运算符都将被送入rpn栈顶\n",
    "                # 若当前运算符为右括号，则弹出stk_op栈顶运算符直到栈顶运算符为左括号\n",
    "                # 所有被弹出的运算符都会被压入rpn栈顶\n",
    "                else:\n",
    "                    while priority_table[s[i]] <= priority_table[stk_op[-1]]:\n",
    "                        rpn.append(stk_op.pop())\n",
    "                    \n",
    "                    # 如果当前运算符为右括号，此前已将左括号到右括号之间的运算符全部送入rpn栈\n",
    "                    # 则栈顶运算符为左括号，将左右括号舍弃\n",
    "                    if s[i] == ')':\n",
    "                        stk_op.pop()\n",
    "\n",
    "                    # 否则将当前运算符压入stk_op栈顶\n",
    "                    else:\n",
    "                        stk_op.append(s[i])\n",
    "                i += 1\n",
    "            # 将数字入栈\n",
    "            else:\n",
    "                j = i\n",
    "                while j < n and s[j].isdigit():\n",
    "                    j += 1\n",
    "                rpn.append(s[i:j])\n",
    "                i = j\n",
    "        return rpn\n",
    "\n",
    "    def evalRPN(self, tokens):\n",
    "        stk = []\n",
    "        for token in tokens:\n",
    "            if token.lstrip('-').isnumeric():\n",
    "                stk.append(int(token))\n",
    "            else:\n",
    "                num2 = stk.pop()\n",
    "                num1 = stk.pop()\n",
    "                stk.append(self.op(num1, num2, token))\n",
    "        return stk[0]\n",
    "    \n",
    "    def op(self, num1, num2, op):\n",
    "        if op == '+':\n",
    "            return num1 + num2\n",
    "        if op == '-':\n",
    "            return num1 - num2\n",
    "        if op == '*':\n",
    "            return num1 * num2\n",
    "        return int(num1 / num2)\n",
    "\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def to_rpn(s):\n",
    "            s += '#'\n",
    "            f = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "            operators = ['$']\n",
    "            rpn = []\n",
    "            i, n = 0, len(s)\n",
    "            while i < n:\n",
    "                if (priority := f.get(s[i], 0)):\n",
    "                    if s[i] == '(' or priority > f[operators[-1]] > 0:\n",
    "                        operators.append(s[i])\n",
    "                    else:\n",
    "                        while priority <= f[operators[-1]]:\n",
    "                            rpn.append(operators.pop())\n",
    "                        if s[i] == ')':\n",
    "                            operators.pop()\n",
    "                        else:\n",
    "                            operators.append(s[i])\n",
    "                    i += 1\n",
    "                else:\n",
    "                    j = i\n",
    "                    while j < n and s[j].isdigit():\n",
    "                        j += 1\n",
    "                    rpn.append(s[i: j])\n",
    "                    i = j\n",
    "            return rpn\n",
    "\n",
    "        # 计算逆波兰表达式的结果\n",
    "        def calculate_rpn(rpn):\n",
    "            stack = []\n",
    "            for ele in rpn:\n",
    "                if not ele.isdigit():\n",
    "                    num2, num1 = stack.pop(), stack.pop()\n",
    "                    if ele == '*':\n",
    "                        stack.append(num1 * num2)\n",
    "                    elif ele == '/':\n",
    "                        # 规避Python异号整型除法向下取整的问题\n",
    "                        stack.append(int(num1 / num2))\n",
    "                    elif ele == '+':\n",
    "                        stack.append(num1 + num2)\n",
    "                    elif ele == '-':\n",
    "                        stack.append(num1 - num2)\n",
    "                else:\n",
    "                    stack.append(int(ele))\n",
    "            return stack[-1]\n",
    "\n",
    "        return calculate_rpn(to_rpn(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        return self.evalRPN(self.toRPN(s))\n",
    "\n",
    "    def toRPN(self, s):\n",
    "        s += '#' # endding\n",
    "        priority_table = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "        stk_op = ['$']\n",
    "        rpn = []\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] in priority_table:\n",
    "                # 若当前运算符为左括号或比stk_op栈顶运算符优先级更高的运算符，直接放入stk_op栈顶\n",
    "                if s[i] == '(' or priority_table[s[i]] > priority_table[stk_op[-1]] > 0:\n",
    "                    stk_op.append(s[i])\n",
    "                \n",
    "                # 否则弹出弹出stk_op栈顶运算符直到当前运算符优先级大于栈顶运算符优先级\n",
    "                # 如果当前运算符为结束符'#'，stk_op中则直到'$'前的所有运算符都将被送入rpn栈顶\n",
    "                # 若当前运算符为右括号，则弹出stk_op栈顶运算符直到栈顶运算符为左括号\n",
    "                # 所有被弹出的运算符都会被压入rpn栈顶\n",
    "                else:\n",
    "                    while priority_table[s[i]] <= priority_table[stk_op[-1]]:\n",
    "                        rpn.append(stk_op.pop())\n",
    "                    \n",
    "                    # 如果当前运算符为右括号，此前已将左括号到右括号之间的运算符全部送入rpn栈\n",
    "                    # 则栈顶运算符为左括号，将左右括号舍弃\n",
    "                    if s[i] == ')':\n",
    "                        stk_op.pop()\n",
    "\n",
    "                    # 否则将当前运算符压入stk_op栈顶\n",
    "                    else:\n",
    "                        stk_op.append(s[i])\n",
    "                i += 1\n",
    "            # 将数字入栈\n",
    "            else:\n",
    "                j = i\n",
    "                while j < n and s[j].isdigit():\n",
    "                    j += 1\n",
    "                rpn.append(s[i:j])\n",
    "                i = j\n",
    "        return rpn\n",
    "\n",
    "    def evalRPN(self, tokens):\n",
    "        stk = []\n",
    "        for token in tokens:\n",
    "            if token.lstrip('-').isnumeric():\n",
    "                stk.append(int(token))\n",
    "            else:\n",
    "                num2 = stk.pop()\n",
    "                num1 = stk.pop()\n",
    "                stk.append(self.op(num1, num2, token))\n",
    "        return stk[0]\n",
    "    \n",
    "    def op(self, num1, num2, op):\n",
    "        if op == '+':\n",
    "            return num1 + num2\n",
    "        if op == '-':\n",
    "            return num1 - num2\n",
    "        if op == '*':\n",
    "            return num1 * num2\n",
    "        return int(num1 / num2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2) / int(num1)) #(0-3)/4\" python除法取整的原因，这个用例过不了了 python中 // 是向下取整，int是向0取整\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        def pair_cal(v1, v2, op):\n",
    "            if op == '+':\n",
    "                return int(v1) + int(v2)\n",
    "            elif op == '-':\n",
    "                return int(v1) - int(v2)\n",
    "            elif op == '*':\n",
    "                return int(v1) * int(v2)\n",
    "            elif op == '/':\n",
    "                # python里面//是向下取整，比如-3//4=-1，而不是0；需要靠近0取整(测试用例)\n",
    "                return int(int(v1) / int(v2))\n",
    "        \n",
    "        priority = {'*':2, '/':2, '+':1, '-':1, '(':0, ')':0}\n",
    "        stack_num, stack_op = [], []\n",
    "\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] == ' ': # 空格跳过\n",
    "                i += 1\n",
    "                continue\n",
    "\n",
    "            if i >= n:\n",
    "                break\n",
    "            \n",
    "            if '0' <= s[i] <= '9': # 将多位数字组成一个整数，入栈\n",
    "                num = \"\"\n",
    "                while i < n and '0' <= s[i] <= '9':\n",
    "                    num += s[i]\n",
    "                    i += 1\n",
    "                stack_num.append(int(num))\n",
    "            \n",
    "            if i >= n:\n",
    "                break\n",
    "\n",
    "            if s[i] == '(':\n",
    "                stack_op.append('(')\n",
    "\n",
    "            elif s[i] == ')':\n",
    "                while stack_op and stack_op[-1] != '(':\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.pop() # 弹出(\n",
    "            \n",
    "\n",
    "            else:\n",
    "                while stack_op and priority[stack_op[-1]] >= priority[s[i]]:\n",
    "                    op = stack_op.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "                stack_op.append(s[i])\n",
    "\n",
    "            i += 1\n",
    "\n",
    "        while stack_op: # 遍历完成后，栈里可能还剩一个计算符（优先级较低，没能在遍历的时候优先计算了）\n",
    "            op = stack_op.pop()\n",
    "            num1 = stack_num.pop()\n",
    "            num2 = stack_num.pop()\n",
    "            stack_num.append(pair_cal(num2, num1, op)) # 注意num2在表达式前面，作为第一个计算数\n",
    "        return stack_num[-1]\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i < len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(num2 / num1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "        while i < len(s):\n",
    "            if s[i]==\" \": \n",
    "                i += 1 \n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i] == \"(\":\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i] == \")\":\n",
    "                while stack_opt[-1] != \"(\":\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A, B, opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop() # pop \"(\"\n",
    "            else:\n",
    "                while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A, B, opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A, B, opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "\n",
    "\n",
    "        # stack_num = []\n",
    "        # stack_opt = []\n",
    "        # i = 0\n",
    "        # priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        # while i<len(s):\n",
    "        #     if s[i]==' ':\n",
    "        #         i += 1\n",
    "        #         continue\n",
    "        #     if '0'<=s[i]<='9':\n",
    "        #         j = i\n",
    "        #         while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "        #             i += 1\n",
    "        #         num = int(s[j:i+1])\n",
    "        #         stack_num.append(num)\n",
    "        #     elif s[i]=='(':\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     elif s[i]==')':\n",
    "        #         while stack_opt[-1]!='(':\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.pop()\n",
    "        #     else:\n",
    "        #         while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     i += 1\n",
    "\n",
    "        # while stack_opt:\n",
    "        #     opt = stack_opt.pop()\n",
    "        #     A = stack_num.pop()\n",
    "        #     B = stack_num.pop()\n",
    "        #     res = self.calc(A,B,opt)\n",
    "        #     stack_num.append(res)\n",
    "        # return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2)/int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s) # use global queue to sync through recur\n",
    "        s.append('+')\n",
    "\n",
    "        def _calc():\n",
    "            stack = []\n",
    "            num = 0\n",
    "            preop = '+'\n",
    "\n",
    "            while s:\n",
    "                c = s.popleft()\n",
    "\n",
    "                if c.isdigit():\n",
    "                    num = num * 10 + int(c)\n",
    "                \n",
    "                elif c == '(':\n",
    "                    num = _calc()\n",
    "\n",
    "                elif c in \"+-*/)\":\n",
    "                    if preop == '+': stack.append(num)\n",
    "                    elif preop == '-': stack.append(-num)\n",
    "                    elif preop == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif preop == '/':\n",
    "                        stack[-1] = int(stack[-1] / num)\n",
    "                    \n",
    "                    if c == ')': # already collect last num\n",
    "                        break\n",
    "                    \n",
    "                    preop = c\n",
    "                    num = 0\n",
    "            \n",
    "            return sum(stack)\n",
    "        \n",
    "        return _calc()\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calc(self, num1, num2, operator):\n",
    "        if operator == \"+\":\n",
    "            return int(num2) + int(num1)\n",
    "        elif operator == \"-\":\n",
    "            return int(num2) - int(num1)\n",
    "        elif operator == \"*\":\n",
    "            return int(num2) * int(num1)\n",
    "        elif operator == \"/\":\n",
    "            return int(int(num2) / int(num1))\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "        while i < len(s):\n",
    "            if s[i]==\" \": \n",
    "                i += 1 \n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i] == \"(\":\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i] == \")\":\n",
    "                while stack_opt[-1] != \"(\":\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A, B, opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop() # pop \"(\"\n",
    "            else:\n",
    "                while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A, B, opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A, B, opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "\n",
    "\n",
    "        # stack_num = []\n",
    "        # stack_opt = []\n",
    "        # i = 0\n",
    "        # priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        # while i<len(s):\n",
    "        #     if s[i]==' ':\n",
    "        #         i += 1\n",
    "        #         continue\n",
    "        #     if '0'<=s[i]<='9':\n",
    "        #         j = i\n",
    "        #         while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "        #             i += 1\n",
    "        #         num = int(s[j:i+1])\n",
    "        #         stack_num.append(num)\n",
    "        #     elif s[i]=='(':\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     elif s[i]==')':\n",
    "        #         while stack_opt[-1]!='(':\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.pop()\n",
    "        #     else:\n",
    "        #         while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     i += 1\n",
    "\n",
    "        # while stack_opt:\n",
    "        #     opt = stack_opt.pop()\n",
    "        #     A = stack_num.pop()\n",
    "        #     B = stack_num.pop()\n",
    "        #     res = self.calc(A,B,opt)\n",
    "        #     stack_num.append(res)\n",
    "        # return stack_num[-1]\n",
    "    \n",
    "    # def calc(self,num1,num2,opt):\n",
    "    #     if opt=='+':\n",
    "    #         return int(num1)+int(num2)\n",
    "    #     elif opt=='-':\n",
    "    #         return int(num2)-int(num1)\n",
    "    #     elif opt=='*':\n",
    "    #         return int(num2)*int(num1)\n",
    "    #     elif opt=='/':\n",
    "    #         return int(int(num2)/int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s)\n",
    "            \n",
    "        def _calculate() -> int:\n",
    "            stack = []\n",
    "            prev_operator = '+'\n",
    "            num = 0\n",
    "\n",
    "            while s:\n",
    "                char = s.popleft()\n",
    "                if char == '(':\n",
    "                    num = _calculate()\n",
    "\n",
    "                if char.isdigit():\n",
    "                    num = 10 * num + int(char)\n",
    "\n",
    "                if char in \"+-*/)\" or not s:\n",
    "                    if prev_operator == '+':\n",
    "                        stack.append(num)\n",
    "                    elif prev_operator == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif prev_operator == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif prev_operator == '/':\n",
    "                        stack[-1] = int(stack[-1] / float(num))   \n",
    "                    if char == ')': break\n",
    "    \n",
    "                    num = 0\n",
    "                    prev_operator = char\n",
    "                # 遇到右括号返回递归结果\n",
    "            return sum(stack)\n",
    "\n",
    "        return _calculate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        def evaluate(i):\n",
    "            pre_sign, cur_n, st = '+', 0, []\n",
    "\n",
    "            def update(op, v):\n",
    "                if op == \"+\": st.append(v)\n",
    "                elif op == \"-\": st.append(-v)\n",
    "                elif op == \"*\": st.append(st.pop()*v)\n",
    "                elif op == \"/\": st.append(int(st.pop()/v))\n",
    "\n",
    "            while i<len(s):\n",
    "                c = s[i]\n",
    "                if c.isdigit():\n",
    "                    cur_n = cur_n*10 + int(s[i])\n",
    "                elif c in \"+-*/\":\n",
    "                    update(pre_sign, cur_n)\n",
    "                    cur_n, pre_sign = 0, c\n",
    "                elif c == \"(\":\n",
    "                    cur_n, j = evaluate(i+1)\n",
    "                    i = j\n",
    "                elif c ==\")\":\n",
    "                    update(pre_sign, cur_n)\n",
    "                    return sum(st), i\n",
    "                i += 1\n",
    "            update(pre_sign, cur_n)\n",
    "            return sum(st)\n",
    "        \n",
    "        return evaluate(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2) / int(num1))\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        \n",
    "        i = 0\n",
    "\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i <len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i] == '(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while stack_opt[-1] != '(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    v1 = stack_num.pop()\n",
    "                    v2 = stack_num.pop()\n",
    "                    res = self.calc(v1, v2, opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                #print(stack_opt)\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    #print(stack_num, stack_opt)\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "\n",
    "            #print(stack_opt, stack_num)\n",
    "            i += 1\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def cal(self, num1, num2, ops):\n",
    "        if ops == '+':\n",
    "            return num2 + num1\n",
    "        elif ops == '-':\n",
    "            return num2 - num1\n",
    "        elif ops == '*':\n",
    "            return num2 * num1\n",
    "        elif ops == '/':\n",
    "            return int(num2/num1)\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        stack_num = []\n",
    "        stack_ops = []\n",
    "        priority = {'(': 0, ')': 0, '+': 1, '-': 1, '*': 2, '/': 2}\n",
    "\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            \n",
    "            if s[i].isdigit():\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num*10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                \n",
    "                stack_num.append(num)\n",
    "            \n",
    "            elif s[i] == '(':\n",
    "                stack_ops.append(s[i])\n",
    "                i += 1\n",
    "            \n",
    "            elif s[i] == ')':\n",
    "                while stack_ops and stack_ops[-1] != '(':\n",
    "                    ops = stack_ops.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    ans = self.cal(num1, num2, ops)\n",
    "                    stack_num.append(ans)\n",
    "                \n",
    "                stack_ops.pop()\n",
    "                i += 1\n",
    "            \n",
    "            else:\n",
    "                while stack_ops and priority[stack_ops[-1]] >= priority[s[i]]:\n",
    "                    ops = stack_ops.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    ans = self.cal(num1, num2, ops)\n",
    "                    stack_num.append(ans)\n",
    "                \n",
    "                stack_ops.append(s[i])\n",
    "                i += 1\n",
    "        \n",
    "        while stack_ops:\n",
    "            ops = stack_ops.pop()\n",
    "            num1 = stack_num.pop()\n",
    "            num2 = stack_num.pop()\n",
    "            ans = self.cal(num1, num2, ops)\n",
    "            stack_num.append(ans)\n",
    "        \n",
    "        return stack_num[0]\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    op_map = {\n",
    "        \"(\": 0,\n",
    "        \")\": 0,\n",
    "        \"+\": 1, \n",
    "        \"-\": 1,\n",
    "        \"*\": 2,\n",
    "        \"/\": 2,\n",
    "        \"^\": 3\n",
    "    }\n",
    "    def calc(self, num_stack, op_stack):\n",
    "        if len(num_stack) < 2 or not op_stack:\n",
    "            return \n",
    "        b = num_stack.pop()\n",
    "        a = num_stack.pop()\n",
    "        op = op_stack.pop()\n",
    "        \n",
    "        res = 0\n",
    "        if op == '+':\n",
    "            res = a + b \n",
    "        elif op == '-':\n",
    "            res = a - b\n",
    "        elif op == '*':\n",
    "            res = a * b\n",
    "        elif op == '/':\n",
    "            res = int(a / b)\n",
    "        elif op == '^':\n",
    "            res = a ** b\n",
    "        num_stack.append(res)\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = s.replace(\" \", \"\").replace(\"(-\", \"(0-\").replace(\"(+\", \"(0+\")\n",
    "        num_stack = [0]\n",
    "        op_stack = []\n",
    "        i = 0 \n",
    "        while i < len(s):\n",
    "            if s[i].isdigit():\n",
    "                j = i\n",
    "                while i+1 < len(s) and s[i+1].isdigit():\n",
    "                    i += 1\n",
    "                num_stack.append(int(s[j:i+1]))\n",
    "            elif s[i] == '(':\n",
    "                op_stack.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while op_stack[-1] != '(':\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.pop()  # 弹出左括号\n",
    "            else:\n",
    "                while op_stack and self.op_map[op_stack[-1]] >= self.op_map[s[i]]:\n",
    "                    self.calc(num_stack, op_stack)\n",
    "                op_stack.append(s[i])          \n",
    "            i += 1\n",
    "        while op_stack:\n",
    "            self.calc(num_stack, op_stack)\n",
    "        \n",
    "        return num_stack[-1]\n",
    "\n",
    "# class Solution:\n",
    "#     def calc(self, num1, num2, operator):\n",
    "#         if operator == \"+\":\n",
    "#             return int(num2) + int(num1)\n",
    "#         elif operator == \"-\":\n",
    "#             return int(num2) - int(num1)\n",
    "#         elif operator == \"*\":\n",
    "#             return int(num2) * int(num1)\n",
    "#         elif operator == \"/\":\n",
    "#             return int(int(num2) / int(num1))\n",
    "\n",
    "#     def calculate(self, s: str) -> int:\n",
    "#         stack_num = []\n",
    "#         stack_opt = []\n",
    "#         i = 0\n",
    "#         priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "#         while i < len(s):\n",
    "#             if s[i]==\" \": \n",
    "#                 i += 1 \n",
    "#                 continue\n",
    "#             if '0'<=s[i]<='9':\n",
    "#                 j = i\n",
    "#                 while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "#                     i += 1\n",
    "#                 num = int(s[j:i+1])\n",
    "#                 stack_num.append(num)\n",
    "#             elif s[i] == \"(\":\n",
    "#                 stack_opt.append(s[i])\n",
    "#             elif s[i] == \")\":\n",
    "#                 while stack_opt[-1] != \"(\":\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.pop() # pop \"(\"\n",
    "#             else:\n",
    "#                 while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A, B, opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.append(s[i])\n",
    "#             i += 1\n",
    "#         while stack_opt:\n",
    "#             opt = stack_opt.pop()\n",
    "#             A = stack_num.pop()\n",
    "#             B = stack_num.pop()\n",
    "#             res = self.calc(A, B, opt)\n",
    "#             stack_num.append(res)\n",
    "#         return stack_num[-1]\n",
    "\n",
    "\n",
    "        # stack_num = []\n",
    "        # stack_opt = []\n",
    "        # i = 0\n",
    "        # priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        # while i<len(s):\n",
    "        #     if s[i]==' ':\n",
    "        #         i += 1\n",
    "        #         continue\n",
    "        #     if '0'<=s[i]<='9':\n",
    "        #         j = i\n",
    "        #         while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "        #             i += 1\n",
    "        #         num = int(s[j:i+1])\n",
    "        #         stack_num.append(num)\n",
    "        #     elif s[i]=='(':\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     elif s[i]==')':\n",
    "        #         while stack_opt[-1]!='(':\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.pop()\n",
    "        #     else:\n",
    "        #         while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "        #             opt = stack_opt.pop()\n",
    "        #             A = stack_num.pop()\n",
    "        #             B = stack_num.pop()\n",
    "        #             res = self.calc(A,B,opt)\n",
    "        #             stack_num.append(res)\n",
    "        #         stack_opt.append(s[i])\n",
    "        #     i += 1\n",
    "\n",
    "        # while stack_opt:\n",
    "        #     opt = stack_opt.pop()\n",
    "        #     A = stack_num.pop()\n",
    "        #     B = stack_num.pop()\n",
    "        #     res = self.calc(A,B,opt)\n",
    "        #     stack_num.append(res)\n",
    "        # return stack_num[-1]\n",
    "    \n",
    "    # def calc(self,num1,num2,opt):\n",
    "    #     if opt=='+':\n",
    "    #         return int(num1)+int(num2)\n",
    "    #     elif opt=='-':\n",
    "    #         return int(num2)-int(num1)\n",
    "    #     elif opt=='*':\n",
    "    #         return int(num2)*int(num1)\n",
    "    #     elif opt=='/':\n",
    "    #         return int(int(num2)/int(num1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s_l):\n",
    "            cal_stack = []\n",
    "            num = 0\n",
    "            ops = \"+\"\n",
    "            while s_l:\n",
    "                c = s_l.popleft()\n",
    "                if 0<=ord(c)-ord(\"0\")<=9:\n",
    "                    num = num*10+ord(c)-ord(\"0\")\n",
    "                if c == \"(\":\n",
    "                    num = helper(s_l)\n",
    "                if c in [\"+\", \"-\", \"*\", \"/\"] or len(s_l)==0:\n",
    "                    if ops == \"-\":\n",
    "                        cal_stack.append(-num)\n",
    "                    elif ops == \"+\":\n",
    "                        cal_stack.append(num)\n",
    "                    elif ops == \"*\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(prev*num)\n",
    "                    elif ops == \"/\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(int(prev/num))\n",
    "                    num = 0\n",
    "                    ops = c\n",
    "                if c == \")\":\n",
    "                    if ops == \"-\":\n",
    "                        cal_stack.append(-num)\n",
    "                    elif ops == \"+\":\n",
    "                        cal_stack.append(num)\n",
    "                    elif ops == \"*\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(prev*num)\n",
    "                    elif ops == \"/\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(int(prev/num))\n",
    "                    break\n",
    "            \n",
    "            return sum(cal_stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = list(s)\n",
    "        def helper():\n",
    "            myStack = []\n",
    "            num = 0\n",
    "            sign = '+'\n",
    "            while len(s) > 0:\n",
    "                c = s.pop(0)\n",
    "                # print(myStack,c)\n",
    "                if c.isdigit():\n",
    "                    num = num*10 + int(c)\n",
    "                    # continue\n",
    "                if c == '(':\n",
    "                    num = helper()\n",
    "                    # continue\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        myStack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        myStack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        myStack[-1] = myStack[-1]*num\n",
    "                    elif sign == '/':\n",
    "                        myStack[-1] = int(myStack[-1]/float(num))\n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                if c == ')':\n",
    "                    break\n",
    "                # print(\"=>\",myStack)\n",
    "\n",
    "            return sum(myStack)\n",
    "        return helper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def cal(ops, nums):\n",
    "            # print(f'{ops, nums}')\n",
    "            op = ops.pop()\n",
    "            n1 = nums.pop()\n",
    "            n2 = nums.pop()\n",
    "            # n2 = 0 if not nums else nums.pop()\n",
    "            if op == '+':\n",
    "                res = n2 + n1\n",
    "            elif op == '-':\n",
    "                res = n2 - n1\n",
    "            elif op == '*':\n",
    "                res = n2 * n1\n",
    "            else:\n",
    "                res = int(n2 / n1)\n",
    "            nums.append(res)\n",
    "\n",
    "        nums, ops = [], []\n",
    "        i, n = 0, len(s)\n",
    "        prio = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i < n:\n",
    "            if s[i].isdigit():\n",
    "                j = i\n",
    "                while j < n and s[j].isdigit():\n",
    "                    j += 1\n",
    "                nums.append(int(s[i:j]))\n",
    "                i = j\n",
    "            elif s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '(':\n",
    "                ops.append(s[i])\n",
    "                j = i + 1\n",
    "                while j < n and s[j] == ' ':\n",
    "                    j += 1\n",
    "                if j < n and s[j] == '+' or s[j] == '-':\n",
    "                    nums.append(0)\n",
    "                i = j\n",
    "            elif s[i] == ')':\n",
    "                while ops and ops[-1] != '(':\n",
    "                    cal(ops, nums)\n",
    "                ops.pop()\n",
    "                i += 1\n",
    "            else:\n",
    "                while ops and prio[ops[-1]] >= prio[s[i]]:\n",
    "                    cal(ops, nums)\n",
    "                ops.append(s[i])\n",
    "                i += 1\n",
    "        # print(f'{ops, nums}')\n",
    "        while ops:\n",
    "            cal(ops, nums)\n",
    "        return nums[0]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        def core(s):\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "            while (len(s) > 0):\n",
    "                c = s.popleft()\n",
    "\n",
    "                if c.isdigit():\n",
    "                    num = num * 10 + int(c)\n",
    "                if c == '(':\n",
    "                    num = core(s)\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] = stack[-1]*num \n",
    "                    elif sign == '/':\n",
    "                        stack[-1] = int(stack[-1] / num)\n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                if c == ')': break\n",
    "            return sum(stack)\n",
    "        return core(collections.deque(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def cal(num1, num2, op):\n",
    "            if op == \"+\":\n",
    "                return num1 + num2\n",
    "            if op == \"-\":\n",
    "                return num1 - num2\n",
    "            if op == \"*\":\n",
    "                return num1 * num2\n",
    "            if op == \"/\":\n",
    "                return int(num1 / num2)\n",
    "        stack, operators = [], []\n",
    "        n = len(s)\n",
    "        priority = {\"(\": 0, \")\": 0, \"+\": 1, \"-\": 1, \"*\": 2, \"/\": 2}\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i] == \" \":\n",
    "                i += 1\n",
    "            elif s[i].isdigit():\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num * 10 + int(s[i])\n",
    "                    i += 1\n",
    "                stack.append(num)\n",
    "            else:\n",
    "                if s[i] == \"(\":\n",
    "                    operators.append(s[i])\n",
    "                elif s[i] == \")\":\n",
    "                    op = operators.pop(-1)\n",
    "                    while op != \"(\":\n",
    "                        num2 = int(stack.pop(-1))\n",
    "                        num1 = int(stack.pop(-1))\n",
    "                        stack.append(cal(num1, num2, op))\n",
    "                        op = operators.pop(-1)\n",
    "                else:\n",
    "                    while len(operators) > 0 and priority[operators[-1]] >= priority[s[i]]:\n",
    "                        op = operators.pop(-1)\n",
    "                        num2 = int(stack.pop(-1))\n",
    "                        num1 = int(stack.pop(-1))\n",
    "                        stack.append(cal(num1, num2, op))\n",
    "                    operators.append(s[i])\n",
    "                \n",
    "                i += 1\n",
    "                \n",
    "        while len(operators) > 0:\n",
    "            op = operators.pop(-1)\n",
    "            num2 = int(stack.pop(-1))\n",
    "            num1 = int(stack.pop(-1))\n",
    "            stack.append(cal(num1, num2, op))\n",
    "        return stack[-1]\n",
    "\n",
    "# class Solution:\n",
    "#     def calculate(self, s: str) -> int:\n",
    "#         stack_num = []\n",
    "#         stack_opt = []\n",
    "#         i = 0\n",
    "#         priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "#         while i<len(s):\n",
    "#             if s[i]==' ':\n",
    "#                 i += 1\n",
    "#                 continue\n",
    "#             if '0'<=s[i]<='9':\n",
    "#                 j = i\n",
    "#                 while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "#                     i += 1\n",
    "#                 num = int(s[j:i+1])\n",
    "#                 stack_num.append(num)\n",
    "#             elif s[i]=='(':\n",
    "#                 stack_opt.append(s[i])\n",
    "#             elif s[i]==')':\n",
    "#                 while stack_opt[-1]!='(':\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A,B,opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.pop()\n",
    "#             else:\n",
    "#                 while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "#                     opt = stack_opt.pop()\n",
    "#                     A = stack_num.pop()\n",
    "#                     B = stack_num.pop()\n",
    "#                     res = self.calc(A,B,opt)\n",
    "#                     stack_num.append(res)\n",
    "#                 stack_opt.append(s[i])\n",
    "#             i += 1\n",
    "#         print(stack_num)\n",
    "#         print(stack_opt)\n",
    "#         while stack_opt:\n",
    "#             opt = stack_opt.pop()\n",
    "#             A = stack_num.pop()\n",
    "#             B = stack_num.pop()\n",
    "#             res = self.calc(A,B,opt)\n",
    "#             stack_num.append(res)\n",
    "#         return stack_num[-1]\n",
    "    \n",
    "#     def calc(self,num1,num2,opt):\n",
    "#         if opt=='+':\n",
    "#             return int(num1)+int(num2)\n",
    "#         elif opt=='-':\n",
    "#             return int(num2)-int(num1)\n",
    "#         elif opt=='*':\n",
    "#             return int(num2)*int(num1)\n",
    "#         elif opt=='/':\n",
    "#             return int(num2)//int(num1)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s):\n",
    "            num = 0\n",
    "            sign = \"+\"\n",
    "            stack = collections.deque()\n",
    "\n",
    "            while len(s)>0:\n",
    "                c = s.pop(0)\n",
    "                if c.isdigit():\n",
    "                    num = num*10 + int(c)\n",
    "                if c==\"(\":\n",
    "                    num = helper(s)\n",
    "                if c in [\"+\", \"-\", \"*\", \"/\", \")\"] or len(s)==0:\n",
    "                    if sign==\"+\":\n",
    "                        stack.append(num)\n",
    "                    elif sign==\"-\":\n",
    "                        stack.append(-num)\n",
    "                    elif sign==\"*\":\n",
    "                        stack[-1] *= num\n",
    "                    elif sign==\"/\":\n",
    "                        stack[-1] = int(stack[-1]/num)\n",
    "                    sign, num = c, 0\n",
    "                if c==\")\":\n",
    "                    break\n",
    "            return sum(stack)\n",
    "        return helper(list(s))\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s):\n",
    "            stack = []\n",
    "            op = '+'\n",
    "            num = 0\n",
    "            while len(s) > 0: \n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = 10 * num + int(c)\n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "                if (not c.isdigit() and c !=' ') or len(s) ==0:\n",
    "                    if op == '+':\n",
    "                        stack.append(num)\n",
    "                    elif op == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif op == '*':\n",
    "                        stack.append(stack.pop() * num)\n",
    "                    elif op == '/':\n",
    "                        # top = stack.pop()\n",
    "                        # if top < 0:\n",
    "                        #    stack.append(int(top / num))\n",
    "                        #else:\n",
    "                        #    stack.append(top // num)\n",
    "                        stack[-1] = int((stack[-1]) / float (num))\n",
    "                    op = c\n",
    "                    num = 0\n",
    "                if c == ')':\n",
    "                    break\n",
    "            return sum(stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        return self.evalRPN(self.toRPN(s))\n",
    "\n",
    "    def toRPN(self, s):\n",
    "        s += '#' # endding\n",
    "        priority_table = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "        stk_op = ['$']\n",
    "        rpn = []\n",
    "        i, n = 0, len(s)\n",
    "        while i < n:\n",
    "            if s[i] in priority_table:\n",
    "                # 若当前运算符为左括号或比stk_op栈顶运算符优先级更高的运算符，直接放入stk_op栈顶\n",
    "                if s[i] == '(' or priority_table[s[i]] > priority_table[stk_op[-1]] > 0:\n",
    "                    stk_op.append(s[i])\n",
    "                \n",
    "                # 否则弹出弹出stk_op栈顶运算符直到当前运算符优先级大于栈顶运算符优先级\n",
    "                # 如果当前运算符为结束符'#'，stk_op中则直到'$'前的所有运算符都将被送入rpn栈顶\n",
    "                # 若当前运算符为右括号，则弹出stk_op栈顶运算符直到栈顶运算符为左括号\n",
    "                # 所有被弹出的运算符都会被压入rpn栈顶\n",
    "                else:\n",
    "                    while priority_table[s[i]] <= priority_table[stk_op[-1]]:\n",
    "                        rpn.append(stk_op.pop())\n",
    "                    \n",
    "                    # 如果当前运算符为右括号，此前已将左括号到右括号之间的运算符全部送入rpn栈\n",
    "                    # 则栈顶运算符为左括号，将左右括号舍弃\n",
    "                    if s[i] == ')':\n",
    "                        stk_op.pop()\n",
    "\n",
    "                    # 否则将当前运算符压入stk_op栈顶\n",
    "                    else:\n",
    "                        stk_op.append(s[i])\n",
    "                i += 1\n",
    "            # 将数字入栈\n",
    "            else:\n",
    "                j = i\n",
    "                while j < n and s[j].isdigit():\n",
    "                    j += 1\n",
    "                rpn.append(s[i:j])\n",
    "                i = j\n",
    "        return rpn\n",
    "\n",
    "    def evalRPN(self, tokens):\n",
    "        stk = []\n",
    "        for token in tokens:\n",
    "            if token.lstrip('-').isnumeric():\n",
    "                stk.append(int(token))\n",
    "            else:\n",
    "                num2 = stk.pop()\n",
    "                num1 = stk.pop()\n",
    "                stk.append(self.op(num1, num2, token))\n",
    "        return stk[0]\n",
    "    \n",
    "    def op(self, num1, num2, op):\n",
    "        if op == '+':\n",
    "            return num1 + num2\n",
    "        if op == '-':\n",
    "            return num1 - num2\n",
    "        if op == '*':\n",
    "            return num1 * num2\n",
    "        return int(num1 / num2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        deq = deque()\n",
    "        for c in s:\n",
    "            deq.append(c)\n",
    "\n",
    "        def cal(s):\n",
    "            stack = []\n",
    "            i = 0\n",
    "            num = 0\n",
    "            sign = '+'\n",
    "            while s:\n",
    "                cur = s.popleft()\n",
    "\n",
    "                if cur.isdigit():\n",
    "                    num = num * 10 + int(cur)\n",
    "                    i += 1\n",
    "\n",
    "                if cur == '(':\n",
    "                    num = cal(s)\n",
    "\n",
    "                if (not cur.isdigit() ) or not s:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] *= num \n",
    "                    elif sign == '/':\n",
    "                        stack[-1] = int(stack[-1]/float(num))\n",
    "\n",
    "                    sign = cur\n",
    "                    num = 0\n",
    "\n",
    "                if cur == ')':\n",
    "                    break\n",
    "\n",
    "                \n",
    "            return sum(stack)                        \n",
    "\n",
    "        return cal(deq)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Operator:\n",
    "    def __init__(self, opr, pri, f):\n",
    "        self.opr = opr\n",
    "        self.pri = pri\n",
    "        self.f = f\n",
    "\n",
    "    def __ge__(self, other):\n",
    "        return self.pri >= other.pri\n",
    "\n",
    "    def __eq__(self, other):\n",
    "        return self.opr == other\n",
    "\n",
    "    def cal(self, x, y):\n",
    "        return self.f(x, y)\n",
    "\n",
    "MULT = Operator(\"*\", 2, lambda x,y: x * y)\n",
    "DIVD = Operator(\"/\", 2, lambda x,y: int(x / y))\n",
    "PLUS = Operator(\"+\", 1, lambda x,y: x + y)\n",
    "MINS = Operator(\"-\", 1, lambda x,y: x - y)\n",
    "LEFT = Operator(\"(\", 0, lambda x,y: 0)\n",
    "RIGT = Operator(\")\", 0, lambda x,y: 0)\n",
    "\n",
    "OPRMAP = {\n",
    "    \"+\": PLUS,\n",
    "    \"-\": MINS,\n",
    "    \"*\": MULT,\n",
    "    \"/\": DIVD,\n",
    "    \"(\": LEFT,\n",
    "    \")\": RIGT\n",
    "}\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = \"(\" + s + \")\"\n",
    "        nums, ops, i, n = [], [], 0, len(s)\n",
    "        def eval():\n",
    "            b = nums.pop()\n",
    "            a = nums.pop()\n",
    "            op = ops.pop()\n",
    "            nums.append(op.cal(a,b))\n",
    "\n",
    "        def NUM(i):\n",
    "            cur = \"\"\n",
    "            while i < n and s[i].isdigit():\n",
    "                cur += s[i]\n",
    "                i += 1\n",
    "            nums.append(int(cur))\n",
    "            return i\n",
    "        \n",
    "        def LEFT(i):\n",
    "            ops.append(OPRMAP[s[i]])\n",
    "            i += 1\n",
    "            while i< n and s[i] == \" \":\n",
    "                i += 1\n",
    "            if i < n and s[i] == '-':\n",
    "                nums.append(0)\n",
    "            return i\n",
    "        \n",
    "        def RIGHT(i):\n",
    "            while ops[-1] != \"(\":\n",
    "                eval()\n",
    "            ops.pop()\n",
    "            return i + 1\n",
    "        \n",
    "        def OPR(i):\n",
    "            cur = OPRMAP[s[i]]\n",
    "            while ops and ops[-1] >= cur:\n",
    "                eval()\n",
    "            ops.append(cur)\n",
    "            return i + 1\n",
    "        \n",
    "        def EMP(i):\n",
    "            return i + 1\n",
    "        \n",
    "        MUTATE = defaultdict(lambda: NUM,{\n",
    "            \"+\": OPR,\n",
    "            \"-\": OPR,\n",
    "            \"*\": OPR,\n",
    "            \"/\": OPR,\n",
    "            \"(\": LEFT,\n",
    "            \")\": RIGHT,\n",
    "            \" \": EMP\n",
    "        })\n",
    "        while i < n:\n",
    "            i = MUTATE[s[i]](i)\n",
    "        \n",
    "        while ops:\n",
    "            eval()\n",
    "        \n",
    "        return nums.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s_l):\n",
    "            cal_stack = []\n",
    "            num = 0\n",
    "            ops = \"+\"\n",
    "            while s_l:\n",
    "                c = s_l.popleft()\n",
    "                if 0<=ord(c)-ord(\"0\")<=9:\n",
    "                    num = num*10+ord(c)-ord(\"0\")\n",
    "                elif c == \"(\":\n",
    "                    num = helper(s_l)\n",
    "                elif c in [\"+\", \"-\", \"*\", \"/\"]:\n",
    "                    if ops == \"-\":\n",
    "                        cal_stack.append(-num)\n",
    "                    elif ops == \"+\":\n",
    "                        cal_stack.append(num)\n",
    "                    elif ops == \"*\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(prev*num)\n",
    "                    elif ops == \"/\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(int(prev/num))\n",
    "                    num = 0\n",
    "                    ops = c\n",
    "                elif c == \")\":\n",
    "                    break\n",
    "            # 最后一位肯定是数字，需要加到stack\n",
    "            if ops == \"-\":\n",
    "                cal_stack.append(-num)\n",
    "            elif ops == \"+\":\n",
    "                cal_stack.append(num)\n",
    "            elif ops == \"*\":\n",
    "                prev = cal_stack.pop()\n",
    "                cal_stack.append(prev*num)\n",
    "            elif ops == \"/\":\n",
    "                prev = cal_stack.pop()\n",
    "                cal_stack.append(int(prev/num))\n",
    "            return sum(cal_stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s + '+')\n",
    "\n",
    "        def _calc():\n",
    "            stack = []\n",
    "            num = 0\n",
    "            preop = '+'\n",
    "\n",
    "            while s:\n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = num * 10 + int(c)\n",
    "                elif c == '(':\n",
    "                    num = _calc()\n",
    "                elif c in \"+-*/)\":\n",
    "                    if preop == '+':\n",
    "                        stack.append(num)\n",
    "                    elif preop == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif preop == '*':\n",
    "                        stack[-1] *= num\n",
    "                    elif preop == '/':\n",
    "                        stack[-1] = int(stack[-1] / num)\n",
    "\n",
    "                    if c == ')': break\n",
    "\n",
    "                    preop = c\n",
    "                    num = 0\n",
    "            \n",
    "            return sum(stack)\n",
    "        \n",
    "        return _calc()\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "\n",
    "        priority = {'(': 0, ')': 0, '+': 1, '-': 1, '*': 2, '/': 2}\n",
    "\n",
    "        i = 0\n",
    "        while i < len(s):\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            \n",
    "            if '0' <= s[i] <= '9':\n",
    "                j = i\n",
    "                while i + 1 < len(s) and '0' <= s[i + 1] <= '9':\n",
    "                    i += 1\n",
    "                stack_num.append(int(s[j: i + 1]))\n",
    "            elif s[i] == '(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while stack_opt[-1] != '(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(self.operation(num1, num2, opt))\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priority[stack_opt[-1]] >= priority[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    num1 = stack_num.pop()\n",
    "                    num2 = stack_num.pop()\n",
    "                    stack_num.append(self.operation(num1, num2, opt))\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            num1 = stack_num.pop()\n",
    "            num2 = stack_num.pop()\n",
    "            stack_num.append(self.operation(num1, num2, opt))\n",
    "        \n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def operation(self, num1, num2, opt):\n",
    "        if opt == '+':\n",
    "            return int(num2) + int(num1)\n",
    "        elif opt == '-':\n",
    "            return int(num2) - int(num1)\n",
    "        elif opt == '*':\n",
    "            return int(num2) * int(num1)\n",
    "        elif opt == '/':\n",
    "            return int(int(num2) / int(num1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "            \n",
    "        def helper(s: List) -> int:\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "\n",
    "            while len(s) > 0:\n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = 10 * num + int(c)\n",
    "                # 遇到左括号开始递归计算 num\n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif sign == '/':\n",
    "                        # python 除法向 0 取整的写法\n",
    "                        stack[-1] = int(stack[-1] / float(num))       \n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                # 遇到右括号返回递归结果\n",
    "                if c == ')': break\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(collections.deque(s))\n",
    "\n",
    "# 作者：labuladong\n",
    "# 链接：https://leetcode.cn/problems/basic-calculator-iii/solutions/1/labuladong-ru-he-shi-xian-yi-ge-ji-suan-84mpt/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s):\n",
    "            stack = []\n",
    "            num = 0\n",
    "            signal = '+'\n",
    "            while len(s) > 0:\n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = num * 10 + int(c) \n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if signal == '+':\n",
    "                        stack.append(num)\n",
    "                    elif signal == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif signal == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif signal == '/':\n",
    "                        stack[-1] = int(stack[-1] / num)\n",
    "                    num = 0\n",
    "                    signal = c\n",
    "                if c == ')':\n",
    "                    break\n",
    "            \n",
    "            return sum(stack)\n",
    "\n",
    "        \n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    c = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    if c=='+':\n",
    "                        res = A+B\n",
    "                    elif c=='-':\n",
    "                        res = B-A\n",
    "                    elif c==\"*\":\n",
    "                        res = A*B\n",
    "                    elif c=='/':\n",
    "                        res = int(B/A)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    c = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    if c=='+':\n",
    "                        res = A+B\n",
    "                    elif c=='-':\n",
    "                        res = B-A\n",
    "                    elif c==\"*\":\n",
    "                        res = A*B\n",
    "                    elif c=='/':\n",
    "                        res = int(B/A)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            c = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            if c=='+':\n",
    "                res = int(A+B)\n",
    "            elif c=='-':\n",
    "                res = B-A\n",
    "            elif c==\"*\":\n",
    "                res = A*B\n",
    "            elif c=='/':\n",
    "                res = int(B/A)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2)/int(num1))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2)/int(num1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = deque(s)\n",
    "        def cal(s):\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "        \n",
    "            while len(s) > 0:\n",
    "                current = s.popleft()\n",
    "                if current.isdigit():\n",
    "                    num = 10 * num + int(current)\n",
    "                if current == '(':\n",
    "                    num = cal(s)\n",
    "                if len(s) == 0 or current in ['+','-','*','/',')']:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    if sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    if sign == '*':\n",
    "                        last_num = stack.pop()\n",
    "                        stack.append(last_num * num)\n",
    "                    if sign == '/':\n",
    "                        last_num = stack.pop()\n",
    "                        stack.append(int(last_num / num))\n",
    "                    sign = current\n",
    "                    num = 0\n",
    "                if current == ')':\n",
    "                    break\n",
    "\n",
    "            print(stack)\n",
    "            return sum(stack)\n",
    "        result = cal(s)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack_num = []\n",
    "        stack_opt = []\n",
    "        i = 0\n",
    "        priorty = {'(':0,')':0,'+':1,'-':1,'*':2,'/':2}\n",
    "        while i<len(s):\n",
    "            if s[i]==' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            if '0'<=s[i]<='9':\n",
    "                j = i\n",
    "                while i+1<len(s) and '0'<=s[i+1]<='9':\n",
    "                    i += 1\n",
    "                num = int(s[j:i+1])\n",
    "                stack_num.append(num)\n",
    "            elif s[i]=='(':\n",
    "                stack_opt.append(s[i])\n",
    "            elif s[i]==')':\n",
    "                while stack_opt[-1]!='(':\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.pop()\n",
    "            else:\n",
    "                while stack_opt and priorty[stack_opt[-1]]>=priorty[s[i]]:\n",
    "                    opt = stack_opt.pop()\n",
    "                    A = stack_num.pop()\n",
    "                    B = stack_num.pop()\n",
    "                    res = self.calc(A,B,opt)\n",
    "                    stack_num.append(res)\n",
    "                stack_opt.append(s[i])\n",
    "            i += 1\n",
    "\n",
    "        while stack_opt:\n",
    "            opt = stack_opt.pop()\n",
    "            A = stack_num.pop()\n",
    "            B = stack_num.pop()\n",
    "            res = self.calc(A,B,opt)\n",
    "            stack_num.append(res)\n",
    "        return stack_num[-1]\n",
    "    \n",
    "    def calc(self,num1,num2,opt):\n",
    "        if opt=='+':\n",
    "            return int(num1)+int(num2)\n",
    "        elif opt=='-':\n",
    "            return int(num2)-int(num1)\n",
    "        elif opt=='*':\n",
    "            return int(num2)*int(num1)\n",
    "        elif opt=='/':\n",
    "            return int(int(num2)/int(num1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        ops_map={\n",
    "            '+':[1,lambda x,y:x+y],\n",
    "            '-':[1,lambda x,y:x-y],\n",
    "            '*':[2,lambda x,y:x*y],\n",
    "            '/':[2,lambda x,y:int(x/y)],\n",
    "        }\n",
    "        def cal(s):\n",
    "            \n",
    "            stack_num=[]\n",
    "            stack_ops=[]\n",
    "\n",
    "            num=0\n",
    "\n",
    "            while s:\n",
    "                c=s.popleft()\n",
    "\n",
    "                if c.isdigit():\n",
    "                    num=num*10+int(c)\n",
    "                \n",
    "                elif c=='(':\n",
    "                    num=cal(s)\n",
    "\n",
    "                elif c in ops_map:\n",
    "                    stack_num.append(num)\n",
    "                    while len(stack_num)>=2 and len(stack_ops)>=1 and ops_map[stack_ops[-1]][0]>=ops_map[c][0]:\n",
    "                        l,r=stack_num.pop(),stack_num.pop()\n",
    "                        cur=ops_map[stack_ops.pop()][1](r,l)\n",
    "                        stack_num.append(cur)\n",
    "                    stack_ops.append(c)\n",
    "                    num=0\n",
    "\n",
    "                if len(s)==0:\n",
    "                    stack_num.append(num)\n",
    "                    num=0\n",
    "\n",
    "                elif c==')':\n",
    "                    stack_num.append(num)\n",
    "                    break\n",
    "\n",
    "            while len(stack_ops)>=1 and len(stack_num)>=2:\n",
    "                l,r=stack_num.pop(),stack_num.pop()\n",
    "                cur=ops_map[stack_ops.pop()][1](r,l)\n",
    "                stack_num.append(cur)\n",
    "\n",
    "            return stack_num[0]\n",
    "        \n",
    "        return cal(deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        \n",
    "        def helper(s):\n",
    "            stack, num, sign = [], 0, '+'\n",
    "\n",
    "            while len(s) > 0:\n",
    "                char = s.pop(0)\n",
    "\n",
    "                if char == '(':\n",
    "                    num = helper(s)\n",
    "\n",
    "                if char.isdigit():\n",
    "                    num = num * 10 + int(char)\n",
    "                \n",
    "                if len(s) == 0 or char in [\"+\", \"-\", \"*\", \"/\", \")\"]:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack.append(stack.pop() * num)\n",
    "                    elif sign == '/':\n",
    "                        stack.append(int(stack.pop() / num))\n",
    "                    num, sign = 0, char\n",
    "                \n",
    "                if char == ')':\n",
    "                    break\n",
    "\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(list(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "     def calculate(self, s: str) -> int:\n",
    "        def evaluate(stack):\n",
    "            res = stack.pop(0)\n",
    "            while stack:\n",
    "                op = stack.pop(0)\n",
    "                y = stack.pop(0)\n",
    "                if op == '+':\n",
    "                    res += y\n",
    "                else:\n",
    "                    res -= y\n",
    "            return res\n",
    "\n",
    "        def helper(index):\n",
    "            stack = []\n",
    "            flag = False\n",
    "            cur = ''\n",
    "            while index < len(s):\n",
    "                c = s[index]\n",
    "                if c in '0123456789':\n",
    "                    cur += c\n",
    "                    index += 1\n",
    "                elif c in '+-':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        if flag:\n",
    "                            op = stack.pop()\n",
    "                            y = stack.pop()\n",
    "                            if op == '*':\n",
    "                                stack.append(y * x)\n",
    "                            else:\n",
    "                                stack.append(y // x)\n",
    "                            flag = False\n",
    "                        else:\n",
    "                            stack.append(x)\n",
    "                    stack.append(c)\n",
    "                    index += 1\n",
    "                    cur = ''\n",
    "                elif c in '*/':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        if flag:\n",
    "                            op = stack.pop()\n",
    "                            y = stack.pop()\n",
    "                            if op == '*':\n",
    "                                stack.append(y * x)\n",
    "                            else:\n",
    "                                stack.append(int(y / x))\n",
    "                        else:\n",
    "                            stack.append(x)\n",
    "                    flag = True\n",
    "                    stack.append(c)\n",
    "                    index += 1\n",
    "                    cur = ''\n",
    "                elif c == '(':\n",
    "                    x, index = helper(index + 1)\n",
    "                    if flag:\n",
    "                        op = stack.pop()\n",
    "                        y = stack.pop()\n",
    "                        if op == '*':\n",
    "                            stack.append(y * x)\n",
    "                        else:\n",
    "                            stack.append(int(y / x))\n",
    "                        flag = False\n",
    "                    else:\n",
    "                        stack.append(x)\n",
    "                elif c == ')':\n",
    "                    if cur != '':\n",
    "                        x = int(cur)\n",
    "                        if flag:\n",
    "                            op = stack.pop()\n",
    "                            y = stack.pop()\n",
    "                            if op == '*':\n",
    "                                stack.append(y * x)\n",
    "                            else:\n",
    "                                stack.append(y // x)\n",
    "                        else:\n",
    "                            stack.append(x)\n",
    "                    return evaluate(stack), index + 1\n",
    "\n",
    "            if cur != '':\n",
    "                x = int(cur)\n",
    "                if flag:\n",
    "                    op = stack.pop()\n",
    "                    y = stack.pop()\n",
    "                    if op == '*':\n",
    "                        stack.append(y * x)\n",
    "                    else:\n",
    "                        stack.append(int(y / x))\n",
    "                else:\n",
    "                    stack.append(x)\n",
    "            return evaluate(stack), index + 1\n",
    "\n",
    "        x, _ = helper(0)\n",
    "        return x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s_l):\n",
    "            cal_stack = []\n",
    "            num = 0\n",
    "            ops = \"+\"\n",
    "            while s_l:\n",
    "                c = s_l.popleft()\n",
    "                if 0<=ord(c)-ord(\"0\")<=9:\n",
    "                    num = num*10+ord(c)-ord(\"0\")\n",
    "                elif c == \"(\":\n",
    "                    num = helper(s_l)\n",
    "                elif c in [\"+\", \"-\", \"*\", \"/\"]:\n",
    "                    if ops == \"-\":\n",
    "                        cal_stack.append(-num)\n",
    "                    elif ops == \"+\":\n",
    "                        cal_stack.append(num)\n",
    "                    elif ops == \"*\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(prev*num)\n",
    "                    elif ops == \"/\":\n",
    "                        prev = cal_stack.pop()\n",
    "                        cal_stack.append(int(prev/num))\n",
    "                    num = 0\n",
    "                    ops = c\n",
    "                elif c == \")\":\n",
    "                    \n",
    "                    break\n",
    "            if ops == \"-\":\n",
    "                cal_stack.append(-num)\n",
    "            elif ops == \"+\":\n",
    "                cal_stack.append(num)\n",
    "            elif ops == \"*\":\n",
    "                prev = cal_stack.pop()\n",
    "                cal_stack.append(prev*num)\n",
    "            elif ops == \"/\":\n",
    "                prev = cal_stack.pop()\n",
    "                cal_stack.append(int(prev/num))\n",
    "            return sum(cal_stack)\n",
    "        return helper(collections.deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        items = []\n",
    "        n = len(s)\n",
    "        \n",
    "        idx = 0\n",
    "        while idx < n:\n",
    "            if s[idx] == '(':\n",
    "                items.append(s[idx])\n",
    "            elif s[idx] == ')':\n",
    "                curResult = self._calculate(items)\n",
    "                items.append(curResult)\n",
    "            elif s[idx] in '+-*/':\n",
    "                items.append(s[idx])\n",
    "            else:                         #num\n",
    "                curNum = 0\n",
    "                start = idx\n",
    "                while start < n and '0' <= s[start] <= '9':\n",
    "                    curNum = curNum * 10 + ord(s[start]) - ord('0')\n",
    "                    start += 1\n",
    "                items.append(curNum)\n",
    "                idx = start - 1\n",
    "            idx += 1\n",
    "        \n",
    "        result = self._calculate(items)\n",
    "        return result\n",
    "    \n",
    "    def _calculate(self, items):\n",
    "        curSeg = []\n",
    "        while items and items[-1] != '(':\n",
    "            tmp = items.pop()\n",
    "            curSeg.append(tmp)\n",
    "        if items:                           # remove ( is any\n",
    "            items.pop()\n",
    "        curSeg.reverse()\n",
    "\n",
    "        # cal * and / \n",
    "        tmpSeg = []\n",
    "        idx = 0\n",
    "        while idx < len(curSeg):\n",
    "            if curSeg[idx] == '*' or curSeg[idx] == '/':\n",
    "                num1 = tmpSeg.pop()\n",
    "                num2 = curSeg[idx + 1]\n",
    "                if curSeg[idx] == '*':\n",
    "                    result = num1 * num2\n",
    "                else:\n",
    "                    result = num1 // num2\n",
    "                    if num1 * num2 < 0:\n",
    "                        result += 1\n",
    "                tmpSeg.append(result)\n",
    "                idx += 2\n",
    "            else:\n",
    "                tmpSeg.append(curSeg[idx])\n",
    "                idx += 1\n",
    "        \n",
    "        # cal + and -\n",
    "        curResult = tmpSeg[0]\n",
    "        idx = 1\n",
    "        while idx < len(tmpSeg):\n",
    "            if tmpSeg[idx] == '+':\n",
    "                curResult += tmpSeg[idx + 1]\n",
    "            else:\n",
    "                curResult -= tmpSeg[idx + 1]\n",
    "            idx += 2\n",
    "        \n",
    "        return curResult\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        check={\"+\":0,\"-\":0,\"*\":1,\"/\":1,\"(\":2,\")\":0,\"#\":-1}\n",
    "        #比较运算符号的优先级\n",
    "        def op(a,b,x):\n",
    "            if x==\"+\":\n",
    "                return a+b\n",
    "            elif x==\"-\":\n",
    "                return a-b\n",
    "            elif x==\"*\":\n",
    "                return a*b\n",
    "            else:\n",
    "                return int(a/b)\n",
    "        num_stack=[]\n",
    "        op_stack=[]\n",
    "        pre=None\n",
    "        s=s+\"#\"\n",
    "        for ch in s:\n",
    "            #数字直接处理\n",
    "            if ch.isdigit():\n",
    "                if pre is None: pre=0\n",
    "                pre=pre*10+int(ch)\n",
    "            else:\n",
    "                if pre is not None:\n",
    "                    num_stack.append(pre)\n",
    "                while op_stack and check[op_stack[-1]]>=check[ch] and op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                if ch==\")\":\n",
    "                    while op_stack[-1]!=\"(\":\n",
    "                        c=op_stack.pop()\n",
    "                        b=num_stack.pop()\n",
    "                        a=num_stack.pop()\n",
    "                        num_stack.append(op(a,b,c))\n",
    "                    op_stack.pop()\n",
    "                else:\n",
    "                    op_stack.append(ch)\n",
    "                #运算符号\n",
    "                pre=None\n",
    "        return num_stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self.ind = 0\n",
    "        self.ordZero = ord('0')\n",
    "        self.chList = [ch for ch in s]\n",
    "        self.sLen = len(s)\n",
    "        return self.calFunc()\n",
    "    \n",
    "    def calFunc(self):\n",
    "        cur = 0\n",
    "        numList = []\n",
    "        charList = []\n",
    "        ch = self.chList[self.ind]\n",
    "        while ch != ')':\n",
    "            if ch == '(':\n",
    "                self.ind += 1\n",
    "                cur = self.calFunc()\n",
    "                print(\"cur : {}, self.ind : {}\".format(cur,self.ind))\n",
    "            elif '0' <= ch <= '9':\n",
    "                cur = cur * 10 + ord(ch) - self.ordZero\n",
    "            else:\n",
    "                if len(charList) > 0:\n",
    "                    if charList[-1] == '*':\n",
    "                        cur *= numList.pop()\n",
    "                        charList.pop()\n",
    "                    elif charList[-1] == '/':\n",
    "                        cur = int(numList.pop() / cur)\n",
    "                        charList.pop()\n",
    "\n",
    "                numList.append(cur)\n",
    "                charList.append(ch)\n",
    "                cur = 0\n",
    "\n",
    "            self.ind += 1\n",
    "            if self.ind >= self.sLen:\n",
    "                break\n",
    "            ch = self.chList[self.ind]\n",
    "\n",
    "        # print(\"cur : {}, charList : {}, numList : {}\".format(cur, charList, numList))\n",
    "        if len(charList) > 0:\n",
    "            if charList[-1] == '*':\n",
    "                cur *= numList.pop()\n",
    "                charList.pop()\n",
    "            elif charList[-1] == '/':\n",
    "                cur = int(numList.pop() / cur)\n",
    "                # print(\"cur : {}, midPop : {}\".format(cur, midPop))\n",
    "                charList.pop()\n",
    "        \n",
    "        numList.append(cur)\n",
    "        # print(\"cur : {}, charList : {}, numList : {}\".format(cur, charList, numList))\n",
    "        midCur = numList.pop(0)\n",
    "        while len(charList) > 0:\n",
    "            midChar = charList.pop(0)\n",
    "            if midChar == '+':\n",
    "                midCur += numList.pop(0)\n",
    "            else:\n",
    "                midCur -= numList.pop(0)\n",
    "        return midCur\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "import math\n",
    "\n",
    "def eval(ops):\n",
    "    n = len(ops)\n",
    "    pt = 0\n",
    "    dq = deque()\n",
    "    while pt < n:\n",
    "        if not dq:\n",
    "            dq.append(ops[pt])\n",
    "            pt += 1\n",
    "        else:\n",
    "            if ops[pt] in ['+', '-']:\n",
    "                dq.append(ops[pt])\n",
    "                dq.append(ops[pt+1])\n",
    "            elif ops[pt] in ['*', '/']:\n",
    "                if ops[pt] == \"*\":\n",
    "                    dq.append(\n",
    "                        dq.pop() * ops[pt + 1]\n",
    "                    )\n",
    "                else:\n",
    "                    dq.append(\n",
    "                        int(dq.pop() / ops[pt + 1])\n",
    "                    )\n",
    "            pt += 2\n",
    "\n",
    "    cur = dq.popleft()\n",
    "    while dq:\n",
    "        op = dq.popleft()\n",
    "        if op == '+':\n",
    "            cur += dq.popleft()\n",
    "        else:\n",
    "            cur -= dq.popleft()\n",
    "    return cur\n",
    "    \n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(words):\n",
    "            if '(' not in words and ')' not in words:\n",
    "                return eval(words)\n",
    "            else:\n",
    "                st = []\n",
    "                lb = 0\n",
    "                br_st = []\n",
    "                cur_st = st\n",
    "\n",
    "                pt = 0\n",
    "                while pt < len(words):\n",
    "                    w = words[pt]\n",
    "                    if w == '(':\n",
    "                        if lb == 0:\n",
    "                            cur_st = br_st\n",
    "                        else:\n",
    "                            cur_st.append(w)\n",
    "                        lb += 1\n",
    "                    elif w == ')':\n",
    "                        lb -= 1\n",
    "                        if lb == 0:\n",
    "                            cur_st = st\n",
    "                            cur_st.append(\n",
    "                                helper(br_st)\n",
    "                            )\n",
    "                            br_st.clear()\n",
    "                        else:\n",
    "                            cur_st.append(w)\n",
    "                    else:\n",
    "                        cur_st.append(w)\n",
    "                    pt += 1\n",
    "                return helper(cur_st)\n",
    "\n",
    "        st = []\n",
    "        lb = 0\n",
    "        br_st = []\n",
    "        cur_st = st\n",
    "\n",
    "        pt = 0\n",
    "\n",
    "        while pt < len(s):\n",
    "            w = s[pt]\n",
    "            if w == '(':\n",
    "                if lb == 0:\n",
    "                    cur_st = br_st\n",
    "                else:\n",
    "                    cur_st.append(w)\n",
    "                lb += 1\n",
    "            elif w == ')':\n",
    "                lb -= 1\n",
    "                if lb == 0:\n",
    "                    cur_st = st\n",
    "                    cur_st.append(\n",
    "                        helper(br_st)\n",
    "                    )\n",
    "                    helper(br_st)\n",
    "                    br_st.clear()\n",
    "                else:\n",
    "                    cur_st.append(w)\n",
    "            else:\n",
    "                if not w.isdigit():\n",
    "                    cur_st.append(w)    \n",
    "                else:\n",
    "                    digit_ = \"\"\n",
    "                    while  pt < len(s) and s[pt].isdigit():\n",
    "                        digit_ += s[pt]\n",
    "                        pt += 1\n",
    "                    cur_st.append(int(digit_))\n",
    "                    pt -= 1\n",
    "            \n",
    "            pt += 1\n",
    "        return helper(cur_st)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def calculate(self, s: str) -> int:\r\n",
    "        def eval():\r\n",
    "            \"\"\"从stack_num中取出两个数, 从stack_op中取出一个操作符, 进行计算并将计算结果存入stack_num\"\"\"\r\n",
    "            # if len(stack_num) < 2 or not stack_op:\r\n",
    "            #     return\r\n",
    "            if len(stack_num) < 1 or not stack_op:          # 操作符不为空, 但只有一个数字时, 取另一个数字为0, 处理\"-\"号或\"\", \r\n",
    "                return\r\n",
    "            \r\n",
    "            op = stack_op.pop()\r\n",
    "            a = stack_num.pop()\r\n",
    "            b = 0 if not stack_num else stack_num.pop()     # 操作符不为空, 但只有一个数字时, 取另一个数字为0, 处理\"+-\"号作为单目运算符的情况. \r\n",
    "\r\n",
    "            if op == '+':\r\n",
    "                res = a + b\r\n",
    "            elif op == '-':\r\n",
    "                res = b - a\r\n",
    "            elif op == '*':\r\n",
    "                res = b * a\r\n",
    "            elif op == '/':\r\n",
    "                sign1 = 1 if b > 0 else -1\r\n",
    "                sign2 = 1 if a > 0 else -1\r\n",
    "                res = sign1 * sign2 * (abs(b) // abs(a))\r\n",
    "            stack_num.append(res)\r\n",
    "\r\n",
    "\r\n",
    "        n = len(s)\r\n",
    "        priority = {'(': 0, \")\": 0, '+':1, '-':1, '*':2, '/':2}    # 定义符号的优先级\r\n",
    "        stack_num = []\r\n",
    "        stack_op = []\r\n",
    "        num = 0\r\n",
    "        num_flag = False\r\n",
    "\r\n",
    "        for i in range(n):\r\n",
    "            ch = s[i]\r\n",
    "            if ch.isdigit():\r\n",
    "                num = num * 10 + ord(ch) - ord('0')\r\n",
    "                num_flag = True\r\n",
    "\r\n",
    "            if i == n - 1 or ch in '+-*/()':  # 数字之后, 到末尾或遇见有效op(数字之后不会存在左括号\"(\")时, 若存在未记录的num, 则将其入栈stack_num.\r\n",
    "                if num_flag:\r\n",
    "                    stack_num.append(num)\r\n",
    "                    num = 0\r\n",
    "                    num_flag = False\r\n",
    "\r\n",
    "            if ch == ' ':\r\n",
    "                continue\r\n",
    "\r\n",
    "            if ch == '(':\r\n",
    "                stack_op.append('(')\r\n",
    "            elif ch == ')':\r\n",
    "                while stack_op and stack_op[-1] != '(':\r\n",
    "                    eval()\r\n",
    "                stack_op.pop()       # 弹出左括号\r\n",
    "            elif ch in '+-*/':\r\n",
    "                while stack_op and priority[stack_op[-1]] >= priority[ch]:    # 栈顶op的优先级大于等于当前op, 则取出栈顶op进行运算\r\n",
    "                    eval()\r\n",
    "                stack_op.append(ch)\r\n",
    "\r\n",
    "        while stack_op:        # 剩余未处理的op. \r\n",
    "            eval()\r\n",
    "\r\n",
    "        return stack_num[-1]   # 返回栈顶数值\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self.nums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']\n",
    "        res, _ = self.helper(s, 0)\n",
    "        return res\n",
    "\n",
    "    def helper(self, s, begin):\n",
    "        print(int(-3/2))\n",
    "        stack = list()\n",
    "        pre_sign = '+'\n",
    "        curr = 0\n",
    "        result = [None, None]\n",
    "        i = begin\n",
    "        while i < len(s):\n",
    "            c = s[i]\n",
    "            if c in self.nums:\n",
    "                curr = curr * 10 + int(c)\n",
    "            if c == '(':\n",
    "                curr, i = self.helper(s, i+1)\n",
    "            if i == len(s) - 1 or c not in self.nums:\n",
    "                if pre_sign == '+':\n",
    "                    stack.append(curr)\n",
    "                elif pre_sign == '-':\n",
    "                    stack.append(-curr)\n",
    "                elif pre_sign == '*':\n",
    "                    stack.append(stack.pop() * curr)\n",
    "                elif pre_sign == '/':\n",
    "                    stack.append(int(stack.pop()/curr))\n",
    "                if c == ')':\n",
    "                    print('yes')\n",
    "                    result[1] = i\n",
    "                    break\n",
    "                pre_sign = c \n",
    "                curr = 0\n",
    "            i += 1\n",
    "        result[0] = sum(stack)\n",
    "        return result\n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s: List) -> int:\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "\n",
    "            while len(s) > 0:\n",
    "                c = s.popleft()\n",
    "                if c.isdigit():\n",
    "                    num = 10 * num + int(c)\n",
    "                # 遇到左括号开始递归计算 num\n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "\n",
    "                if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif sign == '/':\n",
    "                        # python 除法向 0 取整的写法\n",
    "                        stack[-1] = int(stack[-1] / float(num))       \n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                # 遇到右括号返回递归结果\n",
    "                if c == ')': break\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(collections.deque(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def to_rpn(s):\n",
    "            s += '#'\n",
    "            f = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "            operators = ['$']\n",
    "            rpn = []\n",
    "            i, n = 0, len(s)\n",
    "            while i < n:\n",
    "                if (priority := f.get(s[i], 0)):\n",
    "                    if s[i] == '(' or priority > f[operators[-1]] > 0:\n",
    "                        operators.append(s[i])\n",
    "                    else:\n",
    "                        while priority <= f[operators[-1]]:\n",
    "                            rpn.append(operators.pop())\n",
    "                        if s[i] == ')':\n",
    "                            operators.pop()\n",
    "                        else:\n",
    "                            operators.append(s[i])\n",
    "                    i += 1\n",
    "                else:\n",
    "                    j = i\n",
    "                    while j < n and s[j].isdigit():\n",
    "                        j += 1\n",
    "                    rpn.append(s[i: j])\n",
    "                    i = j\n",
    "            return rpn\n",
    "\n",
    "        def calculate_rpn(rpn):\n",
    "            stack = []\n",
    "            for ele in rpn:\n",
    "                if not ele.isdigit():\n",
    "                    num2, num1 = stack.pop(), stack.pop()\n",
    "                    if ele == '*':\n",
    "                        stack.append(num1 * num2)\n",
    "                    elif ele == '/':\n",
    "                        stack.append(int(num1 / num2))\n",
    "                    elif ele == '+':\n",
    "                        stack.append(num1 + num2)\n",
    "                    elif ele == '-':\n",
    "                        stack.append(num1 - num2)\n",
    "                else:\n",
    "                    stack.append(int(ele))\n",
    "            return stack[-1]\n",
    "\n",
    "        return calculate_rpn(to_rpn(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def __init__(self):\n",
    "        self.opMap = {\n",
    "            '+': 1,\n",
    "            '-': 1,\n",
    "            '*': 2,\n",
    "            '/': 2,\n",
    "            '%': 2,\n",
    "            '^': 3\n",
    "        }\n",
    "\n",
    "        self.ops = []\n",
    "        self.nums = [0]\n",
    "\n",
    "    def isNum(self, c):\n",
    "        if c >= '0' and c <= '9':\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "    def cal(self):\n",
    "        if len(self.nums) < 2 or len(self.ops) < 1:\n",
    "            return\n",
    "\n",
    "        b = self.nums.pop(-1)\n",
    "        a = self.nums.pop(-1)\n",
    "        op = self.ops.pop(-1)\n",
    "\n",
    "        if op == '+':\n",
    "            n = a + b\n",
    "        elif op == '-':\n",
    "            n = a - b\n",
    "        elif op == '*':\n",
    "            n = a * b\n",
    "        elif op == '/':\n",
    "            n = int(a / b)\n",
    "        elif op == '%':\n",
    "            n = a % b\n",
    "        elif op == '^':\n",
    "            n = a ^ b\n",
    "        else:\n",
    "            raise RuntimeError(\"Error op\")\n",
    "\n",
    "        return n\n",
    "\n",
    "\n",
    "    def calculate(self, s: str):\n",
    "        s = s.replace(' ','')\n",
    "\n",
    "        i = 0\n",
    "        cur = 0\n",
    "        while i < len(s):\n",
    "            if s[i] == '(':\n",
    "                self.ops.append(s[i])\n",
    "            elif s[i] == ')':\n",
    "                while len(self.ops) > 0 and self.ops[-1] != '(':\n",
    "                    n = self.cal()\n",
    "                    self.nums.append(n)\n",
    "                self.ops.pop(-1)\n",
    "            elif self.isNum(s[i]):\n",
    "                while i < len(s) and self.isNum(s[i]):\n",
    "                    cur = cur * 10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                self.nums.append(cur)\n",
    "                cur = 0\n",
    "                continue\n",
    "            else:\n",
    "                op = s[i]\n",
    "                level = self.opMap[op]\n",
    "                while len(self.ops) > 0 and self.ops[-1] != '(' and self.opMap[self.ops[-1]] >= level:\n",
    "                    n = self.cal()\n",
    "                    self.nums.append(n)\n",
    "                self.ops.append(op)\n",
    "            i += 1\n",
    "\n",
    "        while len(self.ops) > 0:\n",
    "            n = self.cal()\n",
    "            self.nums.append(n)\n",
    "\n",
    "        return self.nums[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        #双栈是为了照顾c++  DSA书上的正统的解法\n",
    "        #专门反馈了问题，“向下截断”====“向零取整”\n",
    "        n = len(s)\n",
    "        priority = {'(': 0, ')': 0, '+': 1, '-': 1, '*': 2, '/': 2}\n",
    "        opt_stk = []\n",
    "        num_stk = []\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "                continue\n",
    "            elif s[i].isdigit() != 0:   #把当前这个数字找完\n",
    "                num = int(s[i])\n",
    "                while i+1 < n and s[i+1].isdigit() != 0:\n",
    "                    num = num * 10 + int(s[i+1])\n",
    "                    i += 1\n",
    "                num_stk.append(num)\n",
    "            elif s[i] == '(':\n",
    "                opt_stk.append(s[i])\n",
    "            elif s[i] == ')':           #把当前这个括号里的东西算完\n",
    "                while opt_stk and opt_stk[-1] != '(':\n",
    "                    opt = opt_stk.pop(-1)\n",
    "                    y = num_stk.pop(-1)\n",
    "                    x = num_stk.pop(-1)\n",
    "                    z = self.calc(x, y, opt)\n",
    "                    num_stk.append(z)\n",
    "                opt_stk.pop()\n",
    "            else :                      #是运算符号 加减之前，先把乘除计算完\n",
    "                while opt_stk and priority[opt_stk[-1]] >= priority[s[i]]:\n",
    "                    opt = opt_stk.pop(-1)\n",
    "                    y = num_stk.pop(-1)\n",
    "                    x = num_stk.pop(-1)\n",
    "                    z = self.calc(x, y, opt)\n",
    "                    num_stk.append(z)\n",
    "                opt_stk.append(s[i])\n",
    "                \n",
    "            i += 1\n",
    "\n",
    "        while opt_stk:              #收尾\n",
    "            opt = opt_stk.pop(-1)\n",
    "            y = num_stk.pop(-1)\n",
    "            x = num_stk.pop(-1)\n",
    "            z = self.calc(x, y, opt)\n",
    "            num_stk.append(z)\n",
    "        \n",
    "        return num_stk[-1]\n",
    "\n",
    "    def calc (self, x: int, y: int, opt: chr) -> int:\n",
    "        if opt == '+':\n",
    "            return x + y\n",
    "        elif opt == '-':\n",
    "            return x - y\n",
    "        elif opt == '*':\n",
    "            return x * y\n",
    "        else:\n",
    "            if x / y < 0:\n",
    "                return ceil(x/y)\n",
    "            else:\n",
    "                return floor(x/y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        ops_map={\n",
    "            '+':[1,lambda x,y:x+y],\n",
    "            '-':[1,lambda x,y:x-y],\n",
    "            '*':[2,lambda x,y:x*y],\n",
    "            '/':[2,lambda x,y:int(x/y)],\n",
    "        }\n",
    "        def cal(s):\n",
    "            \n",
    "            stack_num=[]\n",
    "            stack_ops=[]\n",
    "\n",
    "            num=0\n",
    "\n",
    "            while s:\n",
    "                c=s.popleft()\n",
    "\n",
    "                if c.isdigit():\n",
    "                    num=num*10+int(c)\n",
    "                \n",
    "                elif c=='(':\n",
    "                    num=cal(s)\n",
    "\n",
    "                elif c in ops_map:\n",
    "                    stack_num.append(num)\n",
    "                    while len(stack_num)>=2 and len(stack_ops)>=1 and ops_map[stack_ops[-1]][0]>=ops_map[c][0]:\n",
    "                        l,r=stack_num.pop(),stack_num.pop()\n",
    "                        cur=ops_map[stack_ops.pop()][1](r,l)\n",
    "                        stack_num.append(cur)\n",
    "                    stack_ops.append(c)\n",
    "                    num=0\n",
    "\n",
    "                if len(s)==0:\n",
    "                    stack_num.append(num)\n",
    "                    num=0\n",
    "\n",
    "                elif c==')':\n",
    "                    stack_num.append(num)\n",
    "                    break\n",
    "\n",
    "            while len(stack_ops)>=1 and len(stack_num)>=2:\n",
    "                l,r=stack_num.pop(),stack_num.pop()\n",
    "                cur=ops_map[stack_ops.pop()][1](r,l)\n",
    "                stack_num.append(cur)\n",
    "\n",
    "            return sum(stack_num)\n",
    "        \n",
    "        return cal(deque(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def exchange_rpn(s):\n",
    "            s += '#'\n",
    "            f = {'*': 2, '/': 2, '+': 1, '-': 1, ')': -1, '(': -2, '#': -3, '$': -4}\n",
    "            operators = ['$']\n",
    "            rpn = []\n",
    "            i, n = 0, len(s)\n",
    "            while i < n:\n",
    "                if (priority := f.get(s[i], 0)):\n",
    "                    if s[i] == '(' or priority > f[operators[-1]] > 0:\n",
    "                        operators.append(s[i])\n",
    "                    else:\n",
    "                        while priority <= f[operators[-1]]:\n",
    "                            rpn.append(operators.pop())\n",
    "                        if s[i] == ')':\n",
    "                            operators.pop()\n",
    "                        else:\n",
    "                            operators.append(s[i])\n",
    "                    i += 1\n",
    "                else:\n",
    "                    j = i\n",
    "                    while j < n and s[j].isdigit():\n",
    "                        j += 1\n",
    "                    rpn.append(s[i: j])\n",
    "                    i = j\n",
    "            return rpn\n",
    "        def help_func(rpn):\n",
    "            stack = []\n",
    "            for ele in rpn:\n",
    "                if not ele.isdigit():\n",
    "                    num2, num1 = stack.pop(), stack.pop()\n",
    "                    if ele == '*':\n",
    "                        stack.append(num1 * num2)\n",
    "                    elif ele == '/':\n",
    "                        stack.append(int(num1 / num2))\n",
    "                    elif ele == '+':\n",
    "                        stack.append(num1 + num2)\n",
    "                    elif ele == '-':\n",
    "                        stack.append(num1 - num2)\n",
    "                else:\n",
    "                    stack.append(int(ele))\n",
    "            return stack[-1]\n",
    "        return help_func(exchange_rpn(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = s + '+'\n",
    "        n = len(s)\n",
    "        stack = []\n",
    "        tmp = []\n",
    "        pre_sign = '+'\n",
    "        pre_signv = '+'\n",
    "        pre_num = 0\n",
    "        pre_numv = 0\n",
    "        for i in range(n):\n",
    "            if s[i] == '(':\n",
    "                stack.append([pre_sign, tmp, pre_num])\n",
    "                tmp = []\n",
    "                pre_sign = '+'\n",
    "                pre_num = 0\n",
    "            elif s[i].isdigit():\n",
    "                pre_num = pre_num * 10 + int(s[i])\n",
    "            elif s[i] == ')':\n",
    "                pre_signv, tmpv, pre_numv = stack.pop()\n",
    "                # update tmp\n",
    "                if pre_sign == '*':\n",
    "                    tmp.append(tmp.pop() * pre_num)\n",
    "                elif pre_sign == '/':\n",
    "                    tmp.append(int(tmp.pop() / pre_num))\n",
    "                elif pre_sign == '-':\n",
    "                    tmp.append(-pre_num)\n",
    "                else:\n",
    "                    tmp.append(pre_num)\n",
    "\n",
    "                pre_num = sum(tmp)\n",
    "                pre_sign = pre_signv\n",
    "                tmp = tmpv  \n",
    "\n",
    "            elif i== n -1 or s[i] in ['+','-','*','/']:\n",
    "                if pre_sign == '-':\n",
    "                    tmp.append(-pre_num)\n",
    "                elif pre_sign == '+':\n",
    "                    tmp.append(pre_num)\n",
    "                elif pre_sign == '/':\n",
    "                    tmp.append(int(tmp.pop() / pre_num))  \n",
    "                elif pre_sign == '*':\n",
    "                    tmp.append(tmp.pop() * pre_num) \n",
    "                pre_sign = s[i]\n",
    "                pre_num = 0\n",
    "            print(stack, pre_num, pre_sign, tmp)\n",
    "            \n",
    "        # if pre_sign == '*':\n",
    "        #     tmp.append(tmp.pop() * pre_num)\n",
    "        # elif pre_sign == '/':\n",
    "        #     tmp.append(int(tmp.pop() / pre_num))\n",
    "        # elif pre_sign == '-':\n",
    "        #     tmp.append(-pre_num)\n",
    "        # else:\n",
    "        #     tmp.append(pre_num)\n",
    "        return  sum(tmp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\r\n",
    "#     def calculate(self, s: str) -> int:\r\n",
    "#         n = len(s)\r\n",
    "\r\n",
    "#         priority = {'('}\r\n",
    "\r\n",
    "#         stack_num = []\r\n",
    "#         stack_op = []\r\n",
    "#         num = 0\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "#     def eval(self, stack_num, stack_op):\r\n",
    "#         \"\"\"从stack_num中取出两个数, 从stack_op中取出一个操作符, 进行计算并将计算结果存入stack_num\"\"\"\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        \r\n",
    "\r\n",
    "class Solution:\r\n",
    "    def calculate(self, s: str) -> int:\r\n",
    "        res, _ = self.calc(s, 0)\r\n",
    "        return res\r\n",
    "\r\n",
    "    def calc(self, s: str, startidx) -> int:\r\n",
    "        \"\"\"该函数从s[startidx]位置起始计算, 遇见右括号或者遍历完就返回. \"\"\"\r\n",
    "        n = len(s)\r\n",
    "        stack = []\r\n",
    "        prev_op = \"+\"\r\n",
    "        num = 0\r\n",
    "\r\n",
    "        i = startidx\r\n",
    "        while i < n:\r\n",
    "            ch = s[i]\r\n",
    "            if ch.isdigit():\r\n",
    "                num = num * 10 + (ord(s[i]) - ord('0'))\r\n",
    "            \r\n",
    "            # 遇见左括号, 递归调用, 计算括号内的值并返回, 返回得到括号内结果, 以及对应的右括号位置. \r\n",
    "            # 注意返回的值num有可能为负值!!!\r\n",
    "            if ch == '(':\r\n",
    "                num, i = self.calc(s, i + 1)     \r\n",
    "\r\n",
    "            if i == n - 1 or ch in \"+-*/)\":\r\n",
    "                if prev_op == \"+\":\r\n",
    "                    stack.append(num)\r\n",
    "                elif prev_op == '-':\r\n",
    "                    stack.append(-num)\r\n",
    "                elif prev_op == '*':\r\n",
    "                    stack.append(stack.pop() * num)\r\n",
    "                elif prev_op == '/':                     # num可能为负, prev_num也可能为负, 而除法这里要做整除.\r\n",
    "                    prev_num = stack.pop()\r\n",
    "                    # sign1 = -1 if prev_num < 0 else 1\r\n",
    "                    # sign2 = -1 if num < 0 else 1\r\n",
    "                    # stack.append(sign1*sign2*(abs(prev_num) // abs(num)))\r\n",
    "                    if (prev_num < 0 and num < 0) or (prev_num > 0 and num > 0):\r\n",
    "                        stack.append(prev_num // num)\r\n",
    "                    else:\r\n",
    "                        stack.append(-(abs(prev_num)//abs(num)))\r\n",
    "\r\n",
    "                num = 0\r\n",
    "                prev_op = ch\r\n",
    "\r\n",
    "                if ch == ')':\r\n",
    "                    break\r\n",
    "            i += 1\r\n",
    "\r\n",
    "        return sum(stack), i\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s += '+0'\n",
    "        order = {'(':0, '+':1, '-':1, '*':2, '/':2}\n",
    "        operation_stack = collections.deque()\n",
    "        reverse_list = []\n",
    "        num_left = -1\n",
    "        positive_flag = True\n",
    "        for ci, c in enumerate(s):\n",
    "            if c=='-' and ((ci>0 and s[ci-1]=='(') or ci==0):\n",
    "                positive_flag = False\n",
    "                continue\n",
    "            if c.isdigit():\n",
    "                if num_left==-1:\n",
    "                    num_left = ci\n",
    "            else:\n",
    "                if num_left!=-1:\n",
    "                    value = int(s[num_left:ci])\n",
    "                    if not positive_flag:\n",
    "                        value = -value\n",
    "                        positive_flag = True\n",
    "                    reverse_list.append(value)\n",
    "                    num_left = -1\n",
    "                if c == '(':\n",
    "                    operation_stack.append(c)\n",
    "                elif c in '+-*/':\n",
    "                    while operation_stack and order[operation_stack[-1]]>=order[c]:\n",
    "                        reverse_list.append(operation_stack.pop())\n",
    "                    operation_stack.append(c)\n",
    "                elif c == ')':\n",
    "                    while operation_stack and operation_stack[-1]!='(':\n",
    "                        reverse_list.append(operation_stack.pop())\n",
    "                    operation_stack.pop()\n",
    "        num_stack = collections.deque()\n",
    "        def cal(b, a, op):\n",
    "            if op == '+':\n",
    "                return a+b\n",
    "            if op == '-':\n",
    "                return a-b\n",
    "            if op == '*':\n",
    "                return a*b\n",
    "            if op == '/':\n",
    "                flag = 1\n",
    "                if a<0:\n",
    "                    flag = -flag\n",
    "                if b<0:\n",
    "                    flag = -flag\n",
    "                return flag*(abs(a)//abs(b))\n",
    "        print(reverse_list)\n",
    "        for item in reverse_list:\n",
    "            if str(item) not in '+-*/':\n",
    "                num_stack.append(item)\n",
    "            else:\n",
    "                num_stack.append(cal(num_stack.pop(), num_stack.pop(), item))\n",
    "        return num_stack.pop()\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # 获取括号的匹配关系\n",
    "        dic = handleKH(s)\n",
    "        # 递归计算表达式结果\n",
    "        return calcJJ(s, 0, len(s) - 1, dic)\n",
    "\n",
    "# 计算加减，兼顾去括号、数字类型转换\n",
    "def calcJJ(s, start, end, dic):\n",
    "    # 对于纯数字，类型转换后直接返回\n",
    "    if end - start < 10 and s[start: end + 1].strip(\"1234567890\") == \"\":\n",
    "        return int(s[start: end + 1])\n",
    "    # 对于括号体，去括号后继续计算\n",
    "    if s[start] == \"(\" and end == dic[start]:\n",
    "        return calcJJ(s, start + 1, end - 1, dic)\n",
    "    # 分段计算\n",
    "    i, j, res = start, start, 0\n",
    "    add = True  # 初始化加减 --- 第一部分直接加，后续根据符号判断\n",
    "    while j <= end:\n",
    "        # 截取“+/-”之前的部分\n",
    "        while j <= end and s[j] not in [\"+\", \"-\"]:\n",
    "            if s[j] == \"(\":\n",
    "                j = dic[j]\n",
    "            j += 1\n",
    "        # 根据之前的符号决定，是加上截取的部分，还是减去截取的部分\n",
    "        if add:\n",
    "            res += calcCC(s, i, j - 1, dic)\n",
    "        else:\n",
    "            res -= calcCC(s, i, j - 1, dic)\n",
    "        # 更新符号，用于对下一部分的处理\n",
    "        if j <= end:\n",
    "            add = s[j] == \"+\"\n",
    "        # 以符号下一位置作为起始，继续截取下一计算段\n",
    "        j += 1\n",
    "        i = j\n",
    "    return res\n",
    "        \n",
    "# 计算乘除\n",
    "def calcCC(s, start, end, dic):\n",
    "    i, j, res = start, start, 1\n",
    "    multi = True\n",
    "    # 以乘除符号作为分割（括号作为整体），将各部分送入calcJJ中计算后再乘除\n",
    "    while j <= end:\n",
    "        # 截取一个以乘除号分割的部分\n",
    "        while j <= end and s[j] not in [\"*\", \"/\"]:\n",
    "            if s[j] == \"(\":\n",
    "                j = dic[j]\n",
    "            j += 1\n",
    "        # 根据上一次的符号，确定该部分是乘还是除\n",
    "        if multi:\n",
    "            res *= calcJJ(s, i, j - 1, dic)\n",
    "        else:\n",
    "            # python除法“//”默认会向更小的方向（负数为绝对值大的方向）取整，依照用例(0-3)/4此处需纠正\n",
    "            val = calcJJ(s, i, j - 1, dic)\n",
    "            if res % val != 0 and res / val < 0:\n",
    "                res = res // val + 1\n",
    "            else:\n",
    "                res //= val\n",
    "        # 更新符号，确定下一部分是乘还是除\n",
    "        if j <= end:\n",
    "            multi = s[j] == \"*\"\n",
    "        j += 1\n",
    "        i = j\n",
    "    return res\n",
    "\n",
    "def handleKH(s):\n",
    "    dic = {}\n",
    "    stack = deque()\n",
    "    for i in range(len(s)):\n",
    "        if s[i] == \"(\":\n",
    "            stack.append(i)\n",
    "        elif s[i] == \")\":\n",
    "            dic[stack.pop()] = i\n",
    "    return dic\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = s\n",
    "        n = len(s)\n",
    "        stack = []\n",
    "        tmp = []\n",
    "        pre_sign = '+'\n",
    "        pre_signv = '+'\n",
    "        pre_num = 0\n",
    "        pre_numv = 0\n",
    "        for i in range(n):\n",
    "            if s[i] == '(':\n",
    "                stack.append([pre_sign, tmp, pre_num])\n",
    "                tmp = []\n",
    "                pre_sign = '+'\n",
    "                pre_num = 0\n",
    "            elif s[i].isdigit():\n",
    "                pre_num = pre_num * 10 + int(s[i])\n",
    "            elif s[i] == ')':\n",
    "                pre_signv, tmpv, pre_numv = stack.pop()\n",
    "                # update tmp\n",
    "                if pre_sign == '*':\n",
    "                    tmp.append(tmp.pop() * pre_num)\n",
    "                elif pre_sign == '/':\n",
    "                    tmp.append(int(tmp.pop() / pre_num))\n",
    "                elif pre_sign == '-':\n",
    "                    tmp.append(-pre_num)\n",
    "                else:\n",
    "                    tmp.append(pre_num)\n",
    "                \n",
    "                pre_num = sum(tmp)\n",
    "                # print(pre_num)\n",
    "                \n",
    "                # tmpv.append(tmp)\n",
    "                # pre_num = pre_numv\n",
    "                pre_sign = pre_signv\n",
    "                tmp = tmpv  \n",
    "                # tmp.append(pre_num)\n",
    "\n",
    "            elif s[i] in ['+','-','*','/']:\n",
    "                if pre_sign == '-':\n",
    "                    tmp.append(-pre_num)\n",
    "                elif pre_sign == '+':\n",
    "                    tmp.append(pre_num)\n",
    "                elif pre_sign == '/':\n",
    "                    tmp.append(int(tmp.pop() / pre_num))  \n",
    "                elif pre_sign == '*':\n",
    "                    tmp.append(tmp.pop() * pre_num) \n",
    "                pre_sign = s[i]\n",
    "                pre_num = 0\n",
    "            print(stack, pre_num, pre_sign, tmp)\n",
    "            \n",
    "        if pre_sign == '*':\n",
    "            tmp.append(tmp.pop() * pre_num)\n",
    "        elif pre_sign == '/':\n",
    "            tmp.append(int(tmp.pop() / pre_num))\n",
    "        elif pre_sign == '-':\n",
    "            tmp.append(-pre_num)\n",
    "        else:\n",
    "            tmp.append(pre_num)            \n",
    "        return  sum(tmp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        l1, o1 = 0, 1 # 1 for +, -1 for -1\n",
    "        l2, o2 = 1, 1 # 1 for *, -1 for /\n",
    "        idx = 0\n",
    "        # s = ''.join(list(filter(lambda c : c != ' ', s))) #remove all spaces\n",
    "        last = '('\n",
    "        while idx < len(s):                        \n",
    "            if s[idx].isdigit():\n",
    "                num = int(s[idx])\n",
    "                while idx+1 < len(s) and s[idx+1].isdigit():\n",
    "                    idx += 1\n",
    "                    num = num * 10 + int(s[idx])\n",
    "                l2 = l2 * num if o2==1 else int(l2/num)\n",
    "            elif s[idx] == '(':\n",
    "                stack += [l1, o1, l2, o2]\n",
    "                l1, o1 = 0, 1\n",
    "                l2, o2 = 1, 1                \n",
    "            elif s[idx] == ')':\n",
    "                num = l1 + o1*l2\n",
    "                o2, l2 = stack.pop(), stack.pop()\n",
    "                o1, l1 = stack.pop(), stack.pop()\n",
    "                l2 = l2 * num if o2 == 1 else int(l2/num)\n",
    "            elif s[idx] in '+-':                \n",
    "                if idx > 0 and last != '(': # - can be negative sign\n",
    "                    l1 = l1 + o1*l2\n",
    "                o1 = 1 if s[idx] == '+' else -1\n",
    "                l2, o2 = 1, 1\n",
    "            elif s[idx] in '*/':\n",
    "                o2 = 1 if s[idx] == '*' else -1\n",
    "            if s[idx] != ' ':\n",
    "                last = s[idx]\n",
    "            idx += 1\n",
    "        return l1 + o1*l2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def cal(self, stack_num, stack_str):\n",
    "        retN = 0\n",
    "        if stack_str:\n",
    "            c = stack_str.pop()\n",
    "            if c == \"+\":\n",
    "                retN =  stack_num[-1] + stack_num[-2]\n",
    "            elif c == '-':\n",
    "                retN = stack_num[-2] - stack_num[-1]\n",
    "            stack_num.pop()\n",
    "            stack_num.pop()\n",
    "            stack_num.append(retN)  #\n",
    "\n",
    "    def calculate(self, s: 'str') -> 'int':\n",
    "        stack_num = []\n",
    "        stack_str = []\n",
    "        STATE = 0\n",
    "        NUM_STATE = 1\n",
    "        STR_STATE = 2\n",
    "        state = 0\n",
    "        cal_flag = 0\n",
    "        num = 0\n",
    "        i = 0\n",
    "        while i < len(s):\n",
    "            c = s[i]\n",
    "            if c == ' ':\n",
    "                i +=1\n",
    "                continue\n",
    "\n",
    "            if state == STATE:  # 0.刚输入字符\n",
    "                if c >= '0' and c <= '9':  # 是数字转到数字处理\n",
    "                    state = NUM_STATE\n",
    "                    i -= 1\n",
    "                else:\n",
    "\n",
    "                    state = STR_STATE\n",
    "\n",
    "            elif state == NUM_STATE:  # 1.数字处理\n",
    "\n",
    "                if c >= '0' and c <= '9':  # 获取十进制数字\n",
    "                    num = num * 10 + int(c)\n",
    "\n",
    "                else:\n",
    "\n",
    "                    stack_num.append(num)  # 将数字入栈\n",
    "                    num = 0\n",
    "\n",
    "                    if cal_flag == 1:  # 进行计算\n",
    "                        self.cal(stack_num, stack_str)\n",
    "\n",
    "                    i -= 1\n",
    "                    state = STR_STATE\n",
    "\n",
    "            elif state == STR_STATE:  # 2.str处理\n",
    "\n",
    "                if c >= '0' and c <= '9':  # 如果是数字转到数字处理\n",
    "                    i -= 1\n",
    "                    state = NUM_STATE\n",
    "\n",
    "                elif c == \")\":\n",
    "                    self.cal(stack_num, stack_str)\n",
    "\n",
    "                elif c in [\"+\",\"-\"]:\n",
    "                    stack_str.append(c)\n",
    "                    cal_flag = 1\n",
    "                elif c == \"(\":\n",
    "                    state = NUM_STATE\n",
    "                    cal_flag = 0\n",
    "            i += 1\n",
    "        if num !=0 :\n",
    "            stack_num.append(num)\n",
    "            self.cal(stack_num,stack_str)\n",
    "        if num == 0 and len(stack_num)==0:\n",
    "            return 0\n",
    "        return stack_num[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        oplist=[]\n",
    "        num=[]\n",
    "        i=0\n",
    "        while(i<len(s)):\n",
    "            if s[i]==' ':\n",
    "                i+=1\n",
    "            elif s[i] == '(':\n",
    "                oplist.append(s[i])\n",
    "                i+=1\n",
    "            elif s[i] == ')':\n",
    "                oplist.pop()\n",
    "                if oplist and oplist[-1]!='(':\n",
    "                    op=oplist.pop()\n",
    "                    right=num.pop()\n",
    "                    left=num.pop()\n",
    "                    if op=='+':\n",
    "                        num.append(left+right)\n",
    "                    else:\n",
    "                        num.append(left-right)\n",
    "                i+=1\n",
    "            elif s[i] == '+' or s[i] =='-':\n",
    "                op=s[i]\n",
    "                j=i+1\n",
    "                if s[j] == '(':\n",
    "                    oplist.append(op)\n",
    "                    oplist.append(s[j])\n",
    "                    i=j+1\n",
    "                else:\n",
    "                    if s[j]!=' ':\n",
    "                        temp=int(s[j])\n",
    "                    else:\n",
    "                        temp=0\n",
    "                    j+=1\n",
    "                    while(j<len(s) and s[j] not in ['(',')','+','-']):\n",
    "                        if s[j]!=' ':\n",
    "                            temp=temp*10+int(s[j])\n",
    "                        j+=1\n",
    "                    left=num.pop()\n",
    "                    if op=='+':\n",
    "                        num.append(left+temp)\n",
    "                    else:\n",
    "                        num.append(left-temp)\n",
    "                    i=j\n",
    "            else:\n",
    "                temp=int(s[i])\n",
    "                j=i+1\n",
    "                while(j<len(s) and s[j] not in ['(',')','+','-']):\n",
    "                    if s[j]!=' ':\n",
    "                        temp=temp*10+int(s[j])\n",
    "                    j+=1\n",
    "                num.append(temp)\n",
    "                i=j\n",
    "        return num[-1]\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        def total(stack):\n",
    "            while len(stack) > 2:\n",
    "                if stack[1] == \"+\":\n",
    "                    p = stack[0] + stack[2]\n",
    "                else:\n",
    "                    p = stack[0] - stack[2]\n",
    "                stack = stack[3:]\n",
    "                stack.insert(0, p)\n",
    "            return stack\n",
    "\n",
    "\n",
    "        stack = []\n",
    "        k = \"\"\n",
    "        for idx, i in enumerate(s):\n",
    "            if i == \" \":\n",
    "                continue\n",
    "            if i == \"(\":\n",
    "                stack.append([])\n",
    "\n",
    "            elif str(i).isnumeric():\n",
    "                k += str(i)\n",
    "                if idx < len(s) - 1 and str(s[idx + 1]).isnumeric():\n",
    "                    continue\n",
    "                if len(stack) > 0 and isinstance(stack[-1], list):\n",
    "                    stack[-1].append(int(k))\n",
    "                else:\n",
    "                    stack.append(int(k))\n",
    "                k = \"\"\n",
    "            elif i == \"+\" or i == \"-\":\n",
    "                if isinstance(stack[-1], list):\n",
    "                    stack[-1].append(i)\n",
    "                else:\n",
    "                    stack.append(i)\n",
    "            elif i == \")\":\n",
    "                p = stack.pop()\n",
    "                if not isinstance(p, list):\n",
    "                    p = [p]\n",
    "                else:\n",
    "                    p = total(p)\n",
    "\n",
    "                if len(stack) > 0 and isinstance(stack[-1], list):\n",
    "                    stack[-1] += p\n",
    "                else:\n",
    "                    stack += p\n",
    "        stack = total(stack)\n",
    "\n",
    "        return stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s = s.replace(' ', '')\n",
    "        nums = list()\n",
    "        num = 0\n",
    "        fuhao = '+'\n",
    "        for str in s:\n",
    "            if str.isdigit():\n",
    "                num = num * 10 + int(str)\n",
    "            elif str == '(':\n",
    "                nums.append(fuhao + str)\n",
    "                fuhao = '+'\n",
    "            elif str == ')':\n",
    "                self.cal(nums, fuhao, num)\n",
    "                num = 0\n",
    "                fuhao = '+'\n",
    "                while 1:\n",
    "                    now = nums.pop()\n",
    "                    if '-(' == now:\n",
    "                        fuhao = '-'\n",
    "                        break\n",
    "                    elif '+(' == now:\n",
    "                        break\n",
    "                    else:\n",
    "                        num += now\n",
    "            else:\n",
    "                self.cal(nums, fuhao, num)\n",
    "                fuhao = str\n",
    "                num = 0\n",
    "        self.cal(nums, fuhao, num)\n",
    "        result = 0\n",
    "        for b in nums:\n",
    "            result += b\n",
    "        return result\n",
    "\n",
    "    def cal(self, nums, str, num):\n",
    "        return {\n",
    "            '+': lambda nums, num: nums.append(int(num)),\n",
    "            '-': lambda nums, num: nums.append(-int(num))\n",
    "        }[str](nums, num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: 'str') -> 'int':\n",
    "        stack = []\n",
    "        num1, num2 = 0, 0\n",
    "        op = \"\"\n",
    "        res = 0\n",
    "        s = s.replace(\" \", \"\")\n",
    "        tot = len(s)\n",
    "        i = 0\n",
    "        while i < tot:\n",
    "            if s[i] == \")\":\n",
    "                while True:\n",
    "                    num1 = stack.pop()\n",
    "                    op = stack.pop()\n",
    "                    if op != \"+\":\n",
    "                        if len(stack) and stack[-1] == \"-\":\n",
    "                            stack.pop()\n",
    "                            stack.append(\"+\")\n",
    "                            stack.append(-num1)\n",
    "                        else:\n",
    "                            stack.append(num1)\n",
    "                        break\n",
    "                    num2 = stack.pop()\n",
    "                    res = num2 + num1 if op == \"+\" else num2 - num1\n",
    "                    if stack[-1] == \"(\":\n",
    "                        stack.pop()\n",
    "                        if len(stack) and stack[-1] == \"-\":\n",
    "                            stack.pop()\n",
    "                            stack.append(\"+\")\n",
    "                            stack.append(-res)\n",
    "                        else:\n",
    "                            stack.append(res)\n",
    "                        break;\n",
    "                    else:\n",
    "                        stack.append(res)\n",
    "            else:\n",
    "                tmp = \"\"\n",
    "                if str.isnumeric(s[i]):\n",
    "                    tmp += s[i]\n",
    "                    while i + 1 < tot and str.isnumeric(s[i+1]):\n",
    "                        tmp += s[i+1]\n",
    "                        i += 1\n",
    "                    if len(stack) != 0 and stack[-1] == \"-\":\n",
    "                        stack.pop()\n",
    "                        stack.append(\"+\")\n",
    "                        stack.append(-int(tmp))\n",
    "                    else:\n",
    "                        stack.append(int(tmp))\n",
    "                else:\n",
    "                    stack.append(s[i])\n",
    "            i += 1\n",
    "        while stack:\n",
    "            if len(stack) == 1:\n",
    "                break;\n",
    "            num1 = stack.pop()\n",
    "            op = stack.pop()\n",
    "            if len(stack) == 0:\n",
    "                return num1 if op == \"+\" else -num1\n",
    "            num2 = stack.pop()\n",
    "            res = num2 + num1 if op == \"+\" else num2 - num1\n",
    "            stack.append(res)\n",
    "        return stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        s=s.replace(\" \",\"\")\n",
    "        stack=[]\n",
    "        i,n=0,len(s)-1\n",
    "        s=s+'+'\n",
    "        while i<=n:\n",
    "            if s[i]=='(':\n",
    "                stack.append('(')\n",
    "                i+=1\n",
    "            elif s[i]==')':\n",
    "                sum1=0\n",
    "                while stack[-1]!='(':\n",
    "                    sum1+=stack.pop()\n",
    "                if len(stack)>=2 and stack[-2]=='-':\n",
    "                    stack.pop()\n",
    "                    stack[-1]=(-1)*sum1\n",
    "                else:\n",
    "                    stack[-1]=sum1\n",
    "                i+=1\n",
    "            elif s[i]=='+':\n",
    "                if s[i+1].isdigit():\n",
    "                    t=i+2\n",
    "                    while s[t].isdigit():\n",
    "                        t+=1\n",
    "                    stack.append(int(s[i+1:t]))\n",
    "                    i=t\n",
    "                elif s[i+1] in '-+':\n",
    "                    t=i+2\n",
    "                    while s[t].isdigit():\n",
    "                        t+=1\n",
    "                    stack.append(int(s[i+1:t]))\n",
    "                    i=t\n",
    "                else:\n",
    "                    i+=1\n",
    "            elif s[i]=='-':\n",
    "                if s[i+1].isdigit():\n",
    "                    t=i+2\n",
    "                    while s[t].isdigit():\n",
    "                        t+=1\n",
    "                    stack.append((-1)*int(s[i+1:t]))\n",
    "                    i=t\n",
    "                elif s[i+1] in '-+':\n",
    "                    t=i+2\n",
    "                    while s[t].isdigit():\n",
    "                        t+=1\n",
    "                    stack.append(int(s[i+1:t])*(-1))\n",
    "                    i=t\n",
    "                else:\n",
    "                    stack.append('-')\n",
    "                    i+=1\n",
    "            else:\n",
    "                print(i,s[i])\n",
    "                t=i\n",
    "                while s[i].isdigit():\n",
    "                    i+=1\n",
    "                print(i,t)\n",
    "                stack.append(int(s[t:i]))\n",
    "        return sum(stack)\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        s0=[]\n",
    "        s1=[]\n",
    "        cal=['+','-','(',')']\n",
    "        def work(a,b,x):\n",
    "            if x=='+':\n",
    "                return a+b\n",
    "            elif x=='-':\n",
    "                return a-b\n",
    "        for i in range(len(s)):\n",
    "            if s[i]==' ':\n",
    "                continue\n",
    "            if s[i] in cal:\n",
    "                s0.append(s[i])\n",
    "            else:\n",
    "                i=int(s[i])\n",
    "                k=1\n",
    "                while  len(s0)>0 and s0[-1] not in cal:\n",
    "                    t=s0.pop()\n",
    "                    i=t*pow(10,k)+i\n",
    "                    k+=1\n",
    "                s0.append(i)\n",
    "        for i in s0:\n",
    "            if i in ['+','-','(']:\n",
    "                s1.append(i)\n",
    "            else:\n",
    "                if i==')':\n",
    "                    i=s1.pop()\n",
    "                    s1.pop()\n",
    "                while s1 and s1[-1] in ['-','+']:\n",
    "                    x=s1.pop()\n",
    "                    a=s1.pop()\n",
    "                    i=work(a,i,x)\n",
    "                s1.append(i)\n",
    "                \n",
    "        return s1[0]\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        l = []\n",
    "        ts = \"\"\n",
    "        for i in s:\n",
    "            if i == ' ':\n",
    "                if ts != \"\":\n",
    "                    l.append(ts)\n",
    "                    ts = \"\"\n",
    "                continue\n",
    "            elif i == \")\":\n",
    "                if ts != \"\":\n",
    "                    l.append(ts)\n",
    "                    ts = \"\"\n",
    "                t = 0\n",
    "                while True:\n",
    "                    a = l.pop()\n",
    "                    b = l.pop()\n",
    "                    if b == '-':\n",
    "                        t -= int(a)\n",
    "                    if b == '+':\n",
    "                        t += int(a)\n",
    "                    if b == '(':\n",
    "                        t += int(a)\n",
    "                        l.append(t)\n",
    "                        break\n",
    "            elif i == \"(\" or i == \"+\" or i == \"-\":\n",
    "                if ts != \"\":\n",
    "                    l.append(ts)                    \n",
    "                    ts = \"\"\n",
    "                l.append(i)\n",
    "            else:\n",
    "                ts += i\n",
    "        \n",
    "        if ts != \"\":\n",
    "            l.append(ts)\n",
    "        t = int(l[0])\n",
    "        i = 1\n",
    "        while i < len(l):\n",
    "            if l[i] == '+':\n",
    "                i += 1\n",
    "                t += int(l[i])\n",
    "                i += 1\n",
    "            elif l[i] == '-':\n",
    "                i += 1\n",
    "                t -= int(l[i])\n",
    "                i += 1\n",
    "        \n",
    "        return t\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        val = 0\n",
    "        preOp = '+'\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        stack = [None]*n\n",
    "        top = -1\n",
    "        while i < n:\n",
    "            c = s[i]\n",
    "            if c == ' ':\n",
    "                i+=1\n",
    "                continue\n",
    "            if c == '(':\n",
    "                stack[top+1] = (val,preOp)\n",
    "                val = 0\n",
    "                preOp = '+'\n",
    "                top+=1\n",
    "            elif c == ')':\n",
    "                if stack[top][1]=='+':\n",
    "                    val += stack[top][0]\n",
    "                else:\n",
    "                    val = stack[top][0]-val\n",
    "                top-=1\n",
    "            elif c == '+' or c =='-':\n",
    "                preOp = c\n",
    "            else:\n",
    "                j = i\n",
    "                while j < n and '0'<= s[j] <= '9':\n",
    "                    j += 1\n",
    "                num = int(s[i:j])\n",
    "                if preOp =='+':\n",
    "                    val += num\n",
    "                else:\n",
    "                    val -= num\n",
    "                i = j - 1\n",
    "            i+=1\n",
    "        return val"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        def count(a, b, code):\n",
    "            if code == \"+\":\n",
    "                return a + b\n",
    "            return a - b\n",
    "\n",
    "        # 处理\n",
    "        def proc(l):\n",
    "            #print(\"\".join([str(x) for x in l]))\n",
    "            re,code ,stack = 0,\"+\",[]\n",
    "            for c in l:\n",
    "                if c ==\")\":\n",
    "                    t = []\n",
    "                    while 1:\n",
    "                        this_code = stack.pop(-1)\n",
    "                        if this_code ==\"(\":\n",
    "                            break\n",
    "                        else:\n",
    "                            t.append(this_code)\n",
    "                    t.reverse()\n",
    "                    k = proc(t)\n",
    "                    if stack:stack.append(k)\n",
    "                    else:\n",
    "                        re  = count(re,k,code)\n",
    "                        code =\"+\"\n",
    "                elif c==\"(\" or stack:\n",
    "                    stack.append(c)\n",
    "                elif str(c) in \"+-\":\n",
    "                    code = c\n",
    "                else:\n",
    "                    re = count(re,c,code)\n",
    "                    code = \"+\"\n",
    "            return re\n",
    "\n",
    "        #分解s\n",
    "        s = \"\".join(s.split(\" \"))\n",
    "        s1,n,i = [],len(s),0\n",
    "        while i<n:\n",
    "            j = i + 1\n",
    "            if s[i] in \"()+-\":\n",
    "                s1.append(s[i])\n",
    "            else:\n",
    "                while j<n:\n",
    "                    try:\n",
    "                        int(s[j])\n",
    "                    except:\n",
    "                        break\n",
    "                    else:\n",
    "                        j+=1\n",
    "                s1.append(int(s[i:j]))\n",
    "            i = j\n",
    "        return proc(s1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self,s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        '''\n",
    "        括号、运算符、数字\n",
    "        1.先运算\n",
    "        2.栈：遇到(就将之前运算的数字结果以及最后一个运算符压入栈，遇到)就\n",
    "\n",
    "        '''\n",
    "        res,num,sign=0,0,1\n",
    "        opS=[]\n",
    "        for i in s:  \n",
    "            #num:一个完整的数；res:括号内或者没遇到括号的完整的计算结果\n",
    "            if i.isdigit():\n",
    "\n",
    "                num=10*num+(int)(i)\n",
    "\n",
    "                print(num)\n",
    "            elif i=='+' or i=='-':\n",
    "\n",
    "                res=res+sign*num \n",
    "                num=0                \n",
    "                sign=1 if i=='+' else -1\n",
    "            elif i=='(':  \n",
    "                opS.append(res)\n",
    "                opS.append(sign)\n",
    "                res=0\n",
    "                sign=1\n",
    "            elif i==')': \n",
    "                #res:括号里面的结果\n",
    "                res=res+sign*num\n",
    "                num=0\n",
    "                #sign=1\n",
    "                res*=opS.pop()\n",
    "                res+=opS.pop()\n",
    "            #print(res)\n",
    "            elif i==' ':\n",
    "                continue\n",
    "        #print(res)        \n",
    "        res=res+sign*num   \n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import re\n",
    "class Solution:\n",
    "    def tokenize(self, s):\n",
    "        s = s.strip().replace(' ', '')\n",
    "        tokens = re.findall(r'\\d+|\\D', s)\n",
    "        return tokens\n",
    "\n",
    "    def reverse(self, tokens):\n",
    "        ops = []\n",
    "        output = []\n",
    "        pred = {'(':1, '+':2,'-':2}\n",
    "        for t in tokens:\n",
    "            if t.isdigit():\n",
    "                output.append(int(t))\n",
    "            else:\n",
    "                if not ops:\n",
    "                    ops.append(t)\n",
    "                elif t == '(':\n",
    "                    ops.append(t)\n",
    "                elif t == ')':\n",
    "                    while ops and ops[-1] != '(':\n",
    "                        output.append(ops.pop())\n",
    "                    ops.pop()\n",
    "                else:\n",
    "                    while ops and pred[t] <= pred[ops[-1]]:\n",
    "                        output.append(ops.pop())\n",
    "                    ops.append(t)\n",
    "                    \n",
    "        while ops:\n",
    "            output.append(ops.pop())\n",
    "            \n",
    "        return output\n",
    "    \n",
    "    def eval(self, rev):\n",
    "        s = []\n",
    "        for i in rev:\n",
    "            if isinstance(i, int):\n",
    "                s.append(i)\n",
    "            elif i == '+':\n",
    "                r = s.pop()\n",
    "                l = s.pop()\n",
    "                s.append(l+r)\n",
    "            elif i == '-':\n",
    "                r = s.pop()\n",
    "                l = s.pop()\n",
    "                s.append(l-r)\n",
    "        return s[0]\n",
    "    \n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        tokens = self.reverse(self.tokenize(s))\n",
    "        return self.eval(tokens)\n",
    "            \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s):\n",
    "        total = 0\n",
    "        i, signs = 0, [1, 1]\n",
    "        while i < len(s):\n",
    "            c = s[i]\n",
    "            if c.isdigit():\n",
    "                start = i\n",
    "                while i < len(s) and s[i].isdigit():\n",
    "                    i += 1\n",
    "                total += signs.pop() * int(s[start:i])\n",
    "                continue\n",
    "            if c in '+-(':\n",
    "                signs += signs[-1] * (1, -1)[c == '-'],\n",
    "            elif c == ')':\n",
    "                signs.pop()\n",
    "            i += 1\n",
    "        return total\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def calculate(self, s):\n",
    "        \"\"\"\n",
    "        :type s: str\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        num = 0\n",
    "        result = 0\n",
    "        operator = 1\n",
    "        stack = []\n",
    "        \n",
    "        for char in s:\n",
    "            if char == '+':\n",
    "                result += operator * num\n",
    "                num = 0\n",
    "                operator = 1\n",
    "            elif char == '-':\n",
    "                result += operator * num\n",
    "                num = 0\n",
    "                operator = -1\n",
    "            elif char == '(':\n",
    "                stack.append(result)           # 把“(”前的结果和操作符保存起来\n",
    "                stack.append(operator)\n",
    "                num = 0\n",
    "                result = 0\n",
    "                operator = 1                \n",
    "            elif char == ')':\n",
    "                result += operator * num        # 这个result是()中计算的结果\n",
    "                num = 0\n",
    "                result = result * stack.pop()     \n",
    "                result += stack.pop()\n",
    "            elif char != ' ':\n",
    "                num = num*10 + int(char)\n",
    "        result += operator * num\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        sign, value = 1,0\n",
    "        i, num = 0, len(s)\n",
    "        stack = []\n",
    "        while i < num:\n",
    "            if s[i] == \" \":\n",
    "                pass\n",
    "                i+=1\n",
    "            elif s[i] == \"-\":\n",
    "                sign = -1\n",
    "                i+=1\n",
    "            elif s[i] == \"+\":\n",
    "                sign = 1\n",
    "                i+=1\n",
    "            elif s[i] == \"(\":\n",
    "                stack.append(value)\n",
    "                stack.append(sign)\n",
    "                sign, value = 1,0\n",
    "                i+=1\n",
    "            elif s[i] == \")\":\n",
    "                value = stack.pop()*value + stack.pop()\n",
    "                i+=1\n",
    "            elif s[i].isdigit():\n",
    "                temp = int(s[i])\n",
    "                i+=1\n",
    "                while i < num and s[i].isdigit():\n",
    "                    temp = temp*10 + int(s[i])\n",
    "                    i+=1\n",
    "                value += temp * sign\n",
    "        return value\n",
    "                \n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#\n",
    "# @lc app=leetcode.cn id=224 lang=python3\n",
    "#\n",
    "# [224] 基本计算器\n",
    "#\n",
    "\n",
    "\n",
    "# @lc code=start\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        sign = 1\n",
    "        num = 0\n",
    "        res = 0\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                num = num * 10 + int(c)\n",
    "            elif c == '+':\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                sign = 1\n",
    "            elif c == '-':\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                sign = -1\n",
    "            elif c == '(':\n",
    "                stack.append(res)\n",
    "                stack.append(sign)\n",
    "                sign = 1\n",
    "                res = 0\n",
    "            elif c == ')':\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                res = stack.pop() * res + stack.pop()\n",
    "        res += sign * num\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        num_stack, op_stack = [], []\n",
    "\n",
    "        tmp = -1\n",
    "        for c in s:\n",
    "            # print(num_stack,op_stack)\n",
    "            if c.isdigit():\n",
    "                tmp = tmp*10+int(c) if tmp!=-1 else int(c)\n",
    "            else:\n",
    "                if tmp != -1:\n",
    "                    num_stack.append(tmp)\n",
    "                    tmp = -1\n",
    "                if c == '(':\n",
    "                    op_stack.append(c)\n",
    "                elif c == '+' or c == '-' or c == ')':\n",
    "                    while op_stack and op_stack[-1] != '(':\n",
    "                        op = op_stack.pop()\n",
    "                        num2 = num_stack.pop()\n",
    "                        num1 = num_stack.pop()\n",
    "                        if op == '+':\n",
    "                            num_stack.append(num1+num2)\n",
    "                        else:\n",
    "                            num_stack.append(num1-num2)\n",
    "                    if c != ')': \n",
    "                        op_stack.append(c)\n",
    "                    else:\n",
    "                        op_stack.pop()\n",
    "        \n",
    "        if tmp != -1:\n",
    "            num_stack.append(tmp)\n",
    "        while op_stack:\n",
    "            num2 = num_stack.pop()\n",
    "            num1 = num_stack.pop()\n",
    "            if op_stack.pop() == '+':\n",
    "                num_stack.append(num1+num2)\n",
    "            else:\n",
    "                num_stack.append(num1-num2)\n",
    "        return num_stack.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        operator = 1\n",
    "        res = 0\n",
    "        num = 0\n",
    "        for i in range(len(s)):\n",
    "            if s[i] == '(':\n",
    "                stack.append(res)\n",
    "                stack.append(operator)\n",
    "                res = 0\n",
    "                operator = 1\n",
    "                num = 0\n",
    "                \n",
    "            elif s[i] == ')':\n",
    "                res = res + num*operator\n",
    "                operator = stack.pop()\n",
    "                res = stack.pop() + res*operator\n",
    "                num = 0\n",
    "                operator = 1\n",
    "                \n",
    "            elif s[i] == '+':\n",
    "                res = res + num * operator\n",
    "                num = 0\n",
    "                operator = 1\n",
    "            elif s[i] == '-':\n",
    "                res = res + num * operator\n",
    "                num = 0\n",
    "                operator = -1\n",
    "            \n",
    "            elif s[i] != ' ':\n",
    "                num = num*10 + int(s[i])\n",
    "        res = res + num * operator\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calc(self, s: str):\n",
    "\n",
    "        res = 0\n",
    "        # symbol记录符号, num1记录被计算的数\n",
    "        num1 = ''\n",
    "        symbol = ''\n",
    "        for i in range(len(s)):\n",
    "            if s[i] in ['+', '-'] and num1:\n",
    "                if symbol == '+':\n",
    "                    res += int(num1)\n",
    "                elif symbol == '-':\n",
    "                    res -= int(num1)\n",
    "                else:\n",
    "                    res += int(num1)\n",
    "                symbol = s[i]\n",
    "                num1 = ''\n",
    "            else:\n",
    "                num1 += s[i]\n",
    "        if symbol == '+':\n",
    "            res += int(num1)\n",
    "        elif symbol == '-':\n",
    "            res -= int(num1)\n",
    "        else:\n",
    "            res += int(num1)\n",
    "        return res\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "\n",
    "        midd = ''\n",
    "        for i in range(len(s)):\n",
    "            if s[i] == ')':\n",
    "                inner = ''\n",
    "                for j in range(len(midd) - 1, -1, -1):\n",
    "                    if midd[j] == '(':\n",
    "                        res = self.calc(inner)\n",
    "                        # midd = midd.rstrip('(' + inner)\n",
    "                        # midd += str(res)\n",
    "                        midd = midd[:j] + str(res)\n",
    "                        break\n",
    "                    else:\n",
    "                        inner = midd[j] + inner\n",
    "            else:\n",
    "                midd += s[i]\n",
    "            if i == len(s) - 1:\n",
    "                res = self.calc(midd)\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def getnum(s:str,i:int):\n",
    "            if s[i]==\" \":\n",
    "                return getnum(s,i+1)\n",
    "            tmp = i\n",
    "            while tmp<len(s) and s[tmp].isdigit():\n",
    "                tmp+=1\n",
    "            return int(s[i:tmp]),tmp\n",
    "\n",
    "        def kuohao(s,index):\n",
    "            flag = 1\n",
    "            i = index\n",
    "            res = 0\n",
    "            while s[i]==\" \":i+=1\n",
    "            while i<len(s):\n",
    "                if s[i]==\" \":\n",
    "                    i+=1\n",
    "                    continue\n",
    "                if s[i]==\"(\":\n",
    "                    tmp1,i = kuohao(s,i+1)\n",
    "                    res=res+tmp1*flag\n",
    "                    continue\n",
    "                if s[i]==\")\":\n",
    "                    return res,i+1\n",
    "                if s[i]==\"+\":\n",
    "                    flag = 1\n",
    "                    i+=1\n",
    "                    continue\n",
    "                if s[i]==\"-\":\n",
    "                    flag =-1\n",
    "                    i+=1\n",
    "                    continue\n",
    "                a,i = getnum(s,i)\n",
    "                res = res+a*flag\n",
    "            return res,i\n",
    "\n",
    "        res = 0\n",
    "        flag = 1\n",
    "        i = 0\n",
    "        while s[i] == \" \": i += 1\n",
    "        while i < len(s):\n",
    "            if s[i] == \" \":\n",
    "                i += 1\n",
    "                continue\n",
    "            if s[i] == \"(\":\n",
    "                tmp1, i = kuohao(s, i + 1)\n",
    "                res = res + tmp1 * flag\n",
    "                continue\n",
    "            if s[i] == \"+\":\n",
    "                flag=1\n",
    "                i += 1\n",
    "                continue\n",
    "            if s[i] == \"-\":\n",
    "                flag = -1\n",
    "                i += 1\n",
    "                continue\n",
    "            a, i = getnum(s, i)\n",
    "            res = res + a * flag\n",
    "        return res\n",
    "\n",
    "s = Solution()\n",
    "print(s.calculate(\"(1-(4+5+2)-3)+(6+8)\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stk = list()\n",
    "        num = 0\n",
    "        sign = '+'\n",
    "        for i in range(len(s)):\n",
    "            c = s[i]\n",
    "            if c.isdigit():\n",
    "                num = 10 * num + int(c)\n",
    "            if c == \"(\":\n",
    "                stk.append(sign)\n",
    "                stk.append(c)\n",
    "                sign = '+'\n",
    "            if not c.isdigit() and c != ' ' and c != '(' and c != \")\" or i == len(s)-1:\n",
    "                if sign == '+':\n",
    "                    stk.append(num)\n",
    "                elif sign == '-':\n",
    "                    stk.append(-num)\n",
    "                elif sign == '*':\n",
    "                    pre = stk.pop()\n",
    "                    stk.append(pre * num)\n",
    "                elif sign == '/':\n",
    "                    pre = stk.pop()\n",
    "                    stk.append(int(pre / num))\n",
    "                sign = c\n",
    "                num = 0\n",
    "            if c == \")\":\n",
    "                if sign == '+':\n",
    "                    stk.append(num)\n",
    "                elif sign == '-':\n",
    "                    stk.append(-num)\n",
    "                sign = \"+\"\n",
    "                num = 0\n",
    "                temp = 0\n",
    "                ct = stk.pop()\n",
    "                while ct != '(':\n",
    "                    temp += ct\n",
    "                    ct = stk.pop()\n",
    "                ct = stk.pop()\n",
    "                if ct == '+':\n",
    "                    stk.append(temp)\n",
    "                elif ct == '-':\n",
    "                    stk.append(-temp)\n",
    "\n",
    "        res = 0\n",
    "        while stk:\n",
    "            res += stk.pop()\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        ops = [1]\n",
    "        sign = 1\n",
    "\n",
    "        ret = 0\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '+':\n",
    "                sign = ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '-':\n",
    "                sign = -ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '(':\n",
    "                ops.append(sign)\n",
    "                i += 1\n",
    "            elif s[i] == ')':\n",
    "                ops.pop()\n",
    "                i += 1\n",
    "            else:\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num * 10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                ret += num * sign\n",
    "        return ret\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        # 记录数字的符号, 因为题目说没有负数,说明第一个为正数,设为1\n",
    "        sign = 1\n",
    "        # 数字\n",
    "        num = 0\n",
    "        # 结果\n",
    "        res = 0\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                num = num * 10 + int(c)\n",
    "            elif c == \"+\":\n",
    "                res += sign * num\n",
    "                # 为下一次做准备\n",
    "                num = 0\n",
    "                sign = 1\n",
    "            elif c == \"-\":\n",
    "                res += sign * num\n",
    "                # 为下一次做准备\n",
    "                num = 0\n",
    "                sign = -1\n",
    "            elif c == \"(\":\n",
    "                stack.append(res)\n",
    "                stack.append(sign)\n",
    "                sign = 1\n",
    "                res = 0\n",
    "            elif c == \")\":\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                res = stack.pop() * res + stack.pop()\n",
    "        res += sign * num\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        ops = [1]\n",
    "        sign = 1\n",
    " \n",
    "        res = 0\n",
    "        n = len(s)\n",
    "        i=0\n",
    "        while i <n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '+':\n",
    "                sign = ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '-':\n",
    "                sign = -ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '(':\n",
    "                ops.append(sign)\n",
    "                i += 1\n",
    "            elif s[i] == ')':\n",
    "                ops.pop()\n",
    "                i += 1\n",
    "            else:\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num * 10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                res += num * sign\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        ops = [1]\n",
    "        sign = 1\n",
    "\n",
    "        ret = 0\n",
    "        n = len(s)\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '+':\n",
    "                sign = ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '-':\n",
    "                sign = -ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '(':\n",
    "                ops.append(sign)\n",
    "                i += 1\n",
    "            elif s[i] == ')':\n",
    "                ops.pop()\n",
    "                i += 1\n",
    "            else:\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num * 10 + ord(s[i]) - ord('0')\n",
    "                    i += 1\n",
    "                ret += num * sign\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def calculate(self, s):\n",
    "        res, num, sign = 0, 0, 1\n",
    "        stack = []\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                num = 10 * num + int(c)\n",
    "            elif c == \"+\" or c == \"-\":\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                sign = 1 if c == \"+\" else -1\n",
    "            elif c == \"(\":\n",
    "                stack.append(res)\n",
    "                stack.append(sign)\n",
    "                res = 0\n",
    "                sign = 1\n",
    "            elif c == \")\":\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                res *= stack.pop()\n",
    "                res += stack.pop()\n",
    "        res += sign * num\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def cal():\n",
    "            if not nums or len(nums) < 2: return\n",
    "            if not ops: return\n",
    "            b = nums.pop()\n",
    "            a = nums.pop()\n",
    "            op = ops.pop()\n",
    "            t = a+b if op == '+' else a-b\n",
    "            nums.append(t)\n",
    "\n",
    "        s = s.replace(' ', '')\n",
    "        nums = [0]\n",
    "        ops = []\n",
    "        i = 0\n",
    "        while i < len(s):\n",
    "            print(i)\n",
    "            if s[i] == '(':\n",
    "                ops.append('(')\n",
    "            elif s[i] == ')':\n",
    "                while ops and ops[-1] != '(':    \n",
    "                    cal()\n",
    "                if ops:\n",
    "                    ops.pop()\n",
    "            elif s[i].isnumeric():\n",
    "                a = 0\n",
    "                while i < len(s) and s[i].isnumeric():\n",
    "                    a = 10 * a + int(s[i])\n",
    "                    i += 1\n",
    "                i -= 1\n",
    "                nums.append(a)\n",
    "            else:\n",
    "                if i > 0 and s[i-1] == '(':\n",
    "                    nums.append(0)\n",
    "                while ops and ops[-1] != '(': \n",
    "                    cal()\n",
    "                ops.append(s[i])\n",
    "            i += 1\n",
    "        while ops:\n",
    "            cal()\n",
    "        return nums[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        output, cur, sign, stack = 0, 0, 1, []\n",
    "\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                cur = cur*10 + int(c)\n",
    "            elif c in '+-':\n",
    "                output += cur * sign\n",
    "                cur = 0\n",
    "                if c == '+':\n",
    "                    sign = 1\n",
    "                else:\n",
    "                    sign = -1\n",
    "            elif c == '(':\n",
    "                stack.append(output)\n",
    "                stack.append(sign)\n",
    "                output = 0\n",
    "                sign = 1\n",
    "            elif c == ')':\n",
    "                output += cur * sign\n",
    "                output *= stack.pop() # signal before '('\n",
    "                output += stack.pop() # output before '('\n",
    "                cur = 0\n",
    "        \n",
    "        return output + cur * sign"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ops = [1]\n",
    "        sign = 1\n",
    "        ret = 0\n",
    "\n",
    "        i = 0\n",
    "\n",
    "        while i < n:\n",
    "            if s[i] == ' ':\n",
    "                i += 1\n",
    "            elif s[i] == '+':\n",
    "                sign = ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '-':\n",
    "                sign = - ops[-1]\n",
    "                i += 1\n",
    "            elif s[i] == '(':\n",
    "                ops.append(sign)\n",
    "                i += 1\n",
    "            elif s[i] == ')':\n",
    "                ops.pop()\n",
    "                i += 1\n",
    "            else:\n",
    "                num = 0\n",
    "                while i < n and s[i].isdigit():\n",
    "                    num = num * 10 + int(s[i])\n",
    "                    i += 1\n",
    "                \n",
    "                ret += sign * num\n",
    "        \n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        res, num, sign = 0, 0, 1\n",
    "        stack = []\n",
    "        for c in s:\n",
    "            if c.isdigit():\n",
    "                num = 10 * num + int(c)\n",
    "            elif c == \"+\" or c == \"-\":\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                sign = 1 if c == \"+\" else -1\n",
    "            elif c == \"(\":\n",
    "                stack.append(res)\n",
    "                stack.append(sign)\n",
    "                res = 0\n",
    "                sign = 1\n",
    "            elif c == \")\":\n",
    "                res += sign * num\n",
    "                num = 0\n",
    "                res *= stack.pop()\n",
    "                res += stack.pop()\n",
    "        res += sign * num\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        # 数据预处理\n",
    "        s += \"#\"\n",
    "        s = s.replace(\" \", \"\")\n",
    "\n",
    "        val_stack = []\n",
    "        opt_stack = []\n",
    "        # + - ^ ( )\n",
    "        # 0 1 2 3 4\n",
    "        opt_map = {\n",
    "            \"+\": 0, \"-\": 1, \"^\": 2, \"(\": 3, \")\": 4, \"#\": 5\n",
    "        }\n",
    "        is_out = [\n",
    "            #  +      -      ^      (      )     #\n",
    "            [True, True, False, False, True, True],\n",
    "            [True, True, False, False, True, True],\n",
    "            [True, True, True, False, True, True],\n",
    "            [False, False, False, False, True, True],\n",
    "            [False, False, False, False, False, True]\n",
    "        ]\n",
    "\n",
    "        is_last_val_continues = False\n",
    "        last_s_o = None\n",
    "        for s_v in s:\n",
    "            # 处理数字,直接压栈\n",
    "            if s_v.isdigit():\n",
    "                # 处理单位数\n",
    "                if not is_last_val_continues:\n",
    "                    val_stack.append(int(s_v))\n",
    "                # 处理多位数\n",
    "                else:\n",
    "                    val_stack.append(val_stack.pop() * 10 + int(s_v))\n",
    "                is_last_val_continues = True\n",
    "            # 处理操作符\n",
    "            else:\n",
    "                # 判断\"-\"是否为取反运算符\n",
    "                # 判断标准 -3或(-3)   3-4不是\n",
    "                # 2+(3-(-2))\n",
    "                if last_s_o in [None, \"(\"] and s_v == \"-\" and not is_last_val_continues:\n",
    "                    s_v = \"^\"\n",
    "                while len(opt_stack) > 0 and is_out[opt_map[opt_stack[-1]]][opt_map[s_v]]:\n",
    "                    opt_stack_value = opt_stack.pop()\n",
    "                    if opt_stack_value == \"^\":\n",
    "                        val_stack_value = val_stack.pop()\n",
    "                        val_stack.append(-val_stack_value)\n",
    "                    elif opt_stack_value == \"(\":\n",
    "                        break\n",
    "                    else:\n",
    "                        val_stack_value2 = val_stack.pop()\n",
    "                        val_stack_value1 = val_stack.pop()\n",
    "                        val_stack.append(\n",
    "                            val_stack_value1 + val_stack_value2 if opt_stack_value == \"+\" else val_stack_value1 - val_stack_value2)\n",
    "                if s_v not in [\")\", \"#\"]:\n",
    "                    opt_stack.append(s_v)\n",
    "\n",
    "                last_s_o = s_v\n",
    "                is_last_val_continues = False\n",
    "\n",
    "        return val_stack[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def calSub(i):\n",
    "            ans = 0\n",
    "            cur = 0\n",
    "            sign = 1\n",
    "            while i < len(s):\n",
    "                if s[i] == ' ':\n",
    "                    i += 1\n",
    "                    continue\n",
    "                \n",
    "                if s[i] == '(':\n",
    "                    i += 1\n",
    "                    cur, i = calSub(i)\n",
    "                elif s[i] == ')':\n",
    "                    break\n",
    "                elif s[i] == '+':\n",
    "                    ans += cur * sign\n",
    "                    sign = 1\n",
    "                    cur = 0\n",
    "                elif s[i] == '-':\n",
    "                    ans += cur * sign\n",
    "                    sign = -1\n",
    "                    cur = 0\n",
    "                else:\n",
    "                    cur = cur * 10 + int(s[i])\n",
    "\n",
    "                i += 1\n",
    "\n",
    "            ans += cur * sign\n",
    "\n",
    "\n",
    "            return ans, i\n",
    "\n",
    "        ans, _ = calSub(0)\n",
    "        return ans\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = []\n",
    "        tmp = ''\n",
    "        for ch in s:\n",
    "            if ch.isdigit():\n",
    "                tmp += ch\n",
    "            else:\n",
    "                if tmp:\n",
    "                    stack.append(int(tmp))\n",
    "                    tmp = ''\n",
    "                if ch != ' ':\n",
    "                    stack.append(ch)\n",
    "                if ch == ')':\n",
    "                    tmpnum = 0\n",
    "                    while stack.pop() != '(':\n",
    "                        if stack[-1] == '(':\n",
    "                            stack.pop()\n",
    "                            break\n",
    "                        num = stack.pop()\n",
    "                        if stack[-1] == '-':\n",
    "                            num = -num\n",
    "                        tmpnum += num\n",
    "                    stack.append(tmpnum)\n",
    "        if tmp:\n",
    "            stack.append(int(tmp))\n",
    "        tmpnum = 0\n",
    "        while stack:\n",
    "            num = stack.pop()\n",
    "            if stack and stack.pop() == '-':\n",
    "                num = -num\n",
    "            tmpnum += num\n",
    "        return tmpnum\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        i = 0\n",
    "\n",
    "        def calc():\n",
    "            nonlocal i\n",
    "            num = 0\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "\n",
    "            def update(sign, v):\n",
    "                if sign == '+':\n",
    "                    stack.append(v)\n",
    "                elif sign == '-':\n",
    "                    stack.append(-v)\n",
    "                elif sign == '/':\n",
    "                    stack[-1] //= v\n",
    "                elif sign == '*':\n",
    "                    stack[-1] *= v\n",
    "\n",
    "            while i<len(s):\n",
    "                if s[i].isdigit():\n",
    "                    num = num*10+int(s[i])\n",
    "\n",
    "                elif s[i] in '+-*/':\n",
    "                    update(sign, num)\n",
    "                    num = 0\n",
    "                    sign = s[i]\n",
    "\n",
    "                elif s[i] == '(':\n",
    "                    i += 1\n",
    "                    num = calc()\n",
    "\n",
    "                elif s[i] == ')':\n",
    "                    update(sign, num)\n",
    "                    return sum(stack)\n",
    "\n",
    "                i += 1\n",
    "\n",
    "            update(sign, num)\n",
    "            return sum(stack)\n",
    "\n",
    "        return calc()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def process(s, index):\n",
    "            stack = []\n",
    "            while index < len(s):\n",
    "                if s[index] == '(':\n",
    "                    sum_, index = process(s, index + 1)\n",
    "                    stack.append(sum_)\n",
    "                elif s[index] == ' ':\n",
    "                    index += 1\n",
    "                elif s[index] == '+' or s[index] == '-':\n",
    "                    stack.append(s[index])\n",
    "                    index += 1\n",
    "                elif s[index] == ')':\n",
    "                    break\n",
    "                else:\n",
    "                    tem = ''\n",
    "                    while index<len(s) and s[index] not in ['+','-',' ','(',')']:\n",
    "                        tem+=s[index]\n",
    "                        index += 1\n",
    "                    stack.append(tem)\n",
    "            if stack:\n",
    "                if stack[0] == '-':\n",
    "                    stack.pop(0)\n",
    "                    res = -int(stack.pop(0))\n",
    "                else:\n",
    "                    res = int(stack.pop(0))\n",
    "                while stack:\n",
    "                    if stack.pop(0) == '+':\n",
    "                        res += int(stack.pop(0))\n",
    "                    else:\n",
    "                        res -= int(stack.pop(0))\n",
    "                return int(res), index + 1\n",
    "\n",
    "\n",
    "        res, _ = process(s, 0)\n",
    "        return res\n",
    "     \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        val = []\n",
    "        ops = [1]\n",
    "        num = 0\n",
    "        sign = 1\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            if s[i].isnumeric():\n",
    "                num = num * 10 + int(s[i])\n",
    "            if s[i] == '(':\n",
    "                ops.append(ops[-1] * sign)\n",
    "                sign = 1\n",
    "            if s[i] in [\"+\", \"-\",')'] or i == len(s) - 1:\n",
    "                val.append(sign * ops[-1] * num)\n",
    "                if s[i] == \"+\":\n",
    "                    sign = 1\n",
    "                elif s[i] == '-':\n",
    "                    sign = -1\n",
    "                elif s[i] == ')':\n",
    "                    ops.pop()\n",
    "                num = 0\n",
    "        return sum(val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        s = list(s)\n",
    "        stack = []\n",
    "        last_cal = None\n",
    "        for idx, token in enumerate(s):\n",
    "            if token in ['+', '-']:\n",
    "                if len(stack) and stack[-1] == '-':\n",
    "                    if token == '+':\n",
    "                        s[idx] = '-'\n",
    "                        last_cal = '-'\n",
    "                    else:\n",
    "                        s[idx] = '+'\n",
    "                        last_cal = '+'\n",
    "                else:\n",
    "                    last_cal = token\n",
    "            if token == '(':\n",
    "                stack.append(last_cal)\n",
    "                s[idx] = ' '\n",
    "            if token == ')':\n",
    "                stack.pop()\n",
    "                s[idx] = ' '\n",
    "        result = 0\n",
    "        last_cal = None\n",
    "        last_num = 0\n",
    "        for token in s:\n",
    "            if token in ['+', '-']:\n",
    "                if last_cal == None or last_cal == '+':\n",
    "                    result += last_num\n",
    "                else:\n",
    "                    result -=last_num\n",
    "\n",
    "                last_cal = token\n",
    "                last_num = 0\n",
    "            if token >= '0' and token <= '9':\n",
    "                last_num = last_num * 10 + int(token)\n",
    "        \n",
    "        if last_cal == None or last_cal == '+':\n",
    "            result += last_num\n",
    "        else:\n",
    "            result -= last_num\n",
    "                \n",
    "        return result\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self.where = 0\n",
    "        def f():\n",
    "            num_stack = []\n",
    "            sign_stack = []\n",
    "            num_set = set(map(str, range(10)))\n",
    "            cur = 0\n",
    "            while self.where<len(s) and s[self.where]!=')':\n",
    "                if s[self.where] in num_set:\n",
    "                    cur = cur*10+int(s[self.where])\n",
    "                elif s[self.where]=='(':\n",
    "                    self.where += 1\n",
    "                    cur = f()\n",
    "                elif s[self.where] in ('+', '-', '*', '/'):\n",
    "                    if len(sign_stack)>0 and sign_stack[-1] in ('*', '/'):\n",
    "                        num1 = num_stack.pop()\n",
    "                        num2 = cur\n",
    "                        sign = sign_stack.pop()\n",
    "                        if sign == '*':\n",
    "                            num_stack.append(num1*num2)\n",
    "                            sign_stack.append(s[self.where])\n",
    "                        else:\n",
    "                            num_stack.append(num1/num2)\n",
    "                            sign_stack.append(s[self.where])\n",
    "                        cur = 0\n",
    "                    else:\n",
    "                        num_stack.append(cur)\n",
    "                        sign_stack.append(s[self.where])\n",
    "                        cur = 0\n",
    "                self.where += 1\n",
    "            if len(sign_stack)>0 and sign_stack[-1] in ('*', '/'):\n",
    "                num1 = num_stack.pop()\n",
    "                num2 = cur\n",
    "                sign = sign_stack.pop()\n",
    "                if sign == '*':\n",
    "                    num_stack.append(num1*num2)\n",
    "                else:\n",
    "                    num_stack.append(num1//num)\n",
    "            else:\n",
    "                num_stack.append(cur)\n",
    "            ans = num_stack[0]\n",
    "            # 1 2 35\n",
    "            # + - \n",
    "            print(num_stack)\n",
    "            print(sign_stack)\n",
    "            for i in range(len(sign_stack)):\n",
    "                if sign_stack[i]=='+':\n",
    "                    ans += num_stack[i+1]\n",
    "                elif sign_stack[i]=='-':\n",
    "                    ans -= num_stack[i+1]\n",
    "            return ans\n",
    "        return f()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    # 使用递归处理括号的问题\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s: deque):\n",
    "            # 存放数字的栈\n",
    "            stack = list()\n",
    "            # 前一个完整的数字\n",
    "            num = 0\n",
    "            # 前一个数字前的符号,初始化为+\n",
    "            sign = \"+\"\n",
    "            while s:\n",
    "                char = s.popleft()\n",
    "                # 遇到数字,取完整的数字\n",
    "                if char.isdigit():\n",
    "                    num = num * 10 + ((ord(char) - ord(\"0\")))\n",
    "                # 遇到左括号,进入递归计算括号中的值\n",
    "                if char == \"(\":\n",
    "                    num = helper(s)\n",
    "                # 遇到不是数字且非空格,或者最后一个数字,将前一个符号和数字加入栈中\n",
    "                if (not char.isdigit() and char != \" \") or not s:\n",
    "                    if sign == \"+\":\n",
    "                        stack.append(num)\n",
    "                    elif sign == \"-\":\n",
    "                        stack.append(-num)\n",
    "\n",
    "                    sign = char\n",
    "                    num = 0\n",
    "                # 遇到右括号,递归结束,返回递归结果\n",
    "                if char == \")\":\n",
    "                    break\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(deque(s))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s):\n",
    "            # print(s)\n",
    "            stack = []\n",
    "            num = 0\n",
    "            sign = '+'\n",
    "            while s:\n",
    "                c = s.popleft()\n",
    "                if c == \"(\":\n",
    "                    num = helper(s)  \n",
    "                if c.isdigit():\n",
    "                    num = num*10+int(c)  \n",
    "                if c in '+-*/)' or len(s) == 0:\n",
    "                    # print(sign,num,c)\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    if sign =='-':\n",
    "                        stack.append(-num)\n",
    "                    if sign =='*':\n",
    "                        stack.append(stack.pop()*num)\n",
    "                    if sign == '/':\n",
    "                        stack.append(stack.pop()/num)\n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                if c == \")\":\n",
    "                    break\n",
    "                # print(stack)\n",
    "            return sum(stack)\n",
    "        return helper(collections.deque(s))\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        def helper(s: List) -> int:\n",
    "            stack = []\n",
    "            sign = '+'\n",
    "            num = 0\n",
    "            while len(s) > 0:\n",
    "                c = s.popleft() #使用这个不存在i 的问题\n",
    "                # 遇到左括号开始递归计算 num\n",
    "                if c == '(':\n",
    "                    num = helper(s)\n",
    "                if c.isdigit():\n",
    "                    num = 10 * num + int(c)\n",
    "                if c in \"+-*/)\" or len(s) == 0:\n",
    "                    print(c,num)\n",
    "                # if (not c.isdigit() and c != ' ') or len(s) == 0:\n",
    "                    if sign == '+':\n",
    "                        stack.append(num)\n",
    "                    elif sign == '-':\n",
    "                        stack.append(-num)\n",
    "                    elif sign == '*':\n",
    "                        stack[-1] = stack[-1] * num\n",
    "                    elif sign == '/':\n",
    "                        # python 除法向 0 取整的写法\n",
    "                        stack[-1] = int(stack[-1] / float(num))       \n",
    "                    num = 0\n",
    "                    sign = c\n",
    "                # 遇到右括号返回递归结果\n",
    "                if c == ')': break\n",
    "            print(stack)\n",
    "            return sum(stack)\n",
    "\n",
    "        return helper(collections.deque(s))\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import unittest\n",
    "\n",
    "\n",
    "def is_number_char(c):\n",
    "    return ord('0') <= ord(c) <= ord('9')\n",
    "\n",
    "\n",
    "def char_to_number(c):\n",
    "    return ord(c) - ord('0')\n",
    "\n",
    "\n",
    "def reduce_sign(sign_stack: [int]) -> int:\n",
    "    sign = 1\n",
    "    for s in sign_stack:\n",
    "        sign *= s\n",
    "    return sign\n",
    "\n",
    "\n",
    "class SimpleCalculator:\n",
    "    def __init__(self):\n",
    "        self._values = []\n",
    "        self._source = None\n",
    "\n",
    "    def calculate(self, s: str) -> int:\n",
    "        self._source = s\n",
    "        self._values = []\n",
    "\n",
    "        self.expand_expression()\n",
    "        return self.get_sum()\n",
    "\n",
    "    def expand_expression(self):\n",
    "        sign_stack = [1]\n",
    "        sign = 1\n",
    "        nums = self._values\n",
    "        i = 0\n",
    "        while i < len(self._source):\n",
    "            x = self._source[i]\n",
    "            if x == \"(\":\n",
    "                sign_stack.append(sign)\n",
    "                sign = 1\n",
    "            elif x == \")\":\n",
    "                sign_stack.pop()\n",
    "                sign = 1\n",
    "            elif x == \"+\":\n",
    "                sign = 1\n",
    "            elif x == \"-\":\n",
    "                sign = -1\n",
    "            elif is_number_char(x):\n",
    "                s = sign\n",
    "                if len(sign_stack) > 1:\n",
    "                    s *= reduce_sign(sign_stack)\n",
    "\n",
    "                i, num = self.parse_number(i)\n",
    "                nums.append(num * s)\n",
    "\n",
    "            i += 1\n",
    "\n",
    "    def parse_number(self, start):\n",
    "        num_s = ''\n",
    "        j = 0\n",
    "        source_size = len(self._source)\n",
    "        while start + j < source_size:\n",
    "            c = self._source[start + j]\n",
    "            if not is_number_char(c):\n",
    "                break\n",
    "            num_s += c\n",
    "            j += 1\n",
    "        return start + j - 1, int(num_s)\n",
    "\n",
    "    def get_sum(self):\n",
    "        print(self._values)\n",
    "        return sum(self._values)\n",
    "\n",
    "\n",
    "class Solution(SimpleCalculator):\n",
    "    pass\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def calculate(self, s: str) -> int:\n",
    "        stack = [0]*int(3e5+5)\n",
    "        head = -1\n",
    "        s = ''.join(s.split(' '))\n",
    "        print(s)\n",
    "        digit = 0\n",
    "        sign = 1\n",
    "\n",
    "        for i in s:\n",
    "            if i == ')':\n",
    "                # if met ), first deal with end of digit, then quit stack until met (\n",
    "                digit = sign*digit \n",
    "                head += 1\n",
    "                stack[head] = digit\n",
    "\n",
    "                sign = 1\n",
    "                digit = 0\n",
    "\n",
    "                tmp = 0\n",
    "                while head >= 0 and type(stack[head]) is int:\n",
    "                    tmp += stack[head]\n",
    "                    head -= 1\n",
    "                kuohao_sign = 1 if stack[head] == '(+' else -1 \n",
    "                tmp *= kuohao_sign\n",
    "                stack[head] = tmp\n",
    "            elif i == '+':\n",
    "                # if met +, situation: 3+ )+\n",
    "                if digit != 0:\n",
    "                    digit = sign*digit \n",
    "                    head += 1\n",
    "                    stack[head] = digit\n",
    "\n",
    "                sign = 1\n",
    "                digit = 0\n",
    "            elif i == '-':\n",
    "                # 3- +(- 3)-  -3 -(\n",
    "                if head < 0 or digit != 0:\n",
    "                    digit = sign*digit\n",
    "                    head += 1\n",
    "                    stack[head] = digit\n",
    "\n",
    "                sign = -1\n",
    "                digit = 0\n",
    "            elif i == '(':\n",
    "                head += 1\n",
    "                stack[head] = '(+' if sign == 1 else '(-' \n",
    "                sign = 1\n",
    "            else:\n",
    "                digit = digit*10+int(i)\n",
    "            # print(head, stack[head])\n",
    "        if digit != 0:\n",
    "            head += 1\n",
    "            stack[head] = digit*sign\n",
    "        ans = 0\n",
    "        while head >= 0:\n",
    "            # print(stack[head], head)\n",
    "            ans += stack[head]\n",
    "            head -= 1\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
